Commit 8024256d authored by Ken Martin's avatar Ken Martin

remove old MFC code and update vtkMFCWindow

rendering to a memory HDC is not support beyond opengl 1.4
so change the print methods to use FBOs
parent 36fdeace
......@@ -185,11 +185,52 @@ void vtkMFCWindow::DrawDC(CDC* pDC)
float scale = min(fx,fy);
int x = int(scale * float(cxWindow));
int y = int(scale * float(cyWindow));
this->pvtkWin32OpenGLRW->SetupMemoryRendering(cxWindow, cyWindow, pDC->GetSafeHdc());
this->pvtkWin32OpenGLRW->SetUseOffScreenBuffers(true);
this->pvtkWin32OpenGLRW->Render();
HDC memDC = this->pvtkWin32OpenGLRW->GetMemoryDC();
StretchBlt(pDC->GetSafeHdc(),0,0,x,y,memDC,0,0,cxWindow,cyWindow,SRCCOPY);
this->pvtkWin32OpenGLRW->ResumeScreenRendering();
unsigned char *pixels =
this->pvtkWin32OpenGLRW->GetPixelData(0,0,size[0]-1,size[1]-1,0);
// now copy he result to the HDC
int dataWidth = ((cxWindow*3+3)/4)*4;
BITMAPINFO MemoryDataHeader;
MemoryDataHeader.bmiHeader.biSize = 40;
MemoryDataHeader.bmiHeader.biWidth = cxWindow;
MemoryDataHeader.bmiHeader.biHeight = cyWindow;
MemoryDataHeader.bmiHeader.biPlanes = 1;
MemoryDataHeader.bmiHeader.biBitCount = 24;
MemoryDataHeader.bmiHeader.biCompression = BI_RGB;
MemoryDataHeader.bmiHeader.biClrUsed = 0;
MemoryDataHeader.bmiHeader.biClrImportant = 0;
MemoryDataHeader.bmiHeader.biSizeImage = dataWidth*cyWindow;
MemoryDataHeader.bmiHeader.biXPelsPerMeter = 10000;
MemoryDataHeader.bmiHeader.biYPelsPerMeter = 10000;
unsigned char *MemoryData; // the data in the DIBSection
HDC MemoryHdc = (HDC)CreateCompatibleDC(pDC->GetSafeHdc());
HBITMAP dib = CreateDIBSection(MemoryHdc,
&MemoryDataHeader, DIB_RGB_COLORS,
(void **)(&(MemoryData)), NULL, 0);
// copy the pixels over
for (int i = 0; i < cyWindow; i++)
{
for (int j = 0; j < cxWindow; j++)
{
MemoryData[i*dataWidth + j*3] = pixels[i*cxWindow*3 + j*3 + 2];
MemoryData[i*dataWidth + j*3 + 1] = pixels[i*cxWindow*3 + j*3 + 1];
MemoryData[i*dataWidth + j*3 + 2] = pixels[i*cxWindow*3 + j*3];
}
}
// Put the bitmap into the device context
SelectObject(MemoryHdc, dib);
StretchBlt(pDC->GetSafeHdc(),0,0,x,y,MemoryHdc,0,0,cxWindow,cyWindow,SRCCOPY);
this->pvtkWin32OpenGLRW->SetUseOffScreenBuffers(false);
delete [] pixels;
}
void vtkMFCWindow::OnSize(UINT nType, int cx, int cy)
......
......@@ -1825,10 +1825,14 @@ int vtkOpenGLRenderWindow::CreateHardwareOffScreenWindow(int width, int height)
assert("pre: positive_height" && height>0);
assert("pre: not_initialized" && !this->OffScreenUseFrameBuffer);
this->CreateAWindow();
if (!this->Initialized)
{
this->CreateAWindow();
this->OpenGLInit();
}
this->MakeCurrent();
this->OpenGLInit();
int result = this->CreateHardwareOffScreenBuffers(width, height);
if (!result)
......
......@@ -54,17 +54,8 @@ vtkWin32OpenGLRenderWindow::vtkWin32OpenGLRenderWindow()
this->CursorHidden = 0;
this->Capabilities = 0;
this->ScreenDeviceContext = (HDC)0;
this->MemoryHdc = (HDC)0;
this->CreatingOffScreenWindow = 0;
this->WindowIdReferenceCount = 0;
this->ScreenMapped = this->Mapped;
this->ScreenWindowSize[0] = this->Size[0];
this->ScreenWindowSize[1] = this->Size[1];
this->ScreenDeviceContext = this->DeviceContext;
this->ScreenDoubleBuffer = this->DoubleBuffer;
this->ScreenContextId = this->ContextId;
}
vtkWin32OpenGLRenderWindow::~vtkWin32OpenGLRenderWindow()
......@@ -705,35 +696,36 @@ void vtkWin32OpenGLRenderWindow::SetupPixelFormatPaletteAndContext(
// create a context
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB =
reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB"));
this->ContextId = 0;
if (wglCreateContextAttribsARB)
{
this->ContextId = 0;
// we believe that these later versions are all compatible with
// OpenGL 3.2 so get a more recent context if we can.
int attemptedVersions[] = {4,5, 4,4, 4,3, 4,2, 4,1, 4,0, 3,3, 3,2};
int attemptedVersions[] = {4,5, 4,4, 4,3, 4,2, 4,1, 4,0, 3,3, 3,2, 3,1, 3,0};
int iContextAttribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, 0,
// WGL_CONTEXT_PROFILE_MASK_ARB,
// WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
// WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0 // End of attributes list
};
for (int i = 0; i < 8 && !this->ContextId; i++)
{
int iContextAttribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
WGL_CONTEXT_FLAGS_ARB, 0,
// WGL_CONTEXT_PROFILE_MASK_ARB,
// WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
// WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0 // End of attributes list
};
iContextAttribs[1] = attemptedVersions[i*2];
iContextAttribs[3] = attemptedVersions[i*2+1];
this->ContextId = wglCreateContextAttribsARB(hDC, 0, iContextAttribs);
}
if (this->ContextId &&
(iContextAttribs[1] >= 4 || iContextAttribs[3] >= 2))
{
this->SetContextSupportsOpenGL32(true);
}
}
if (this->ContextId)
{
this->SetContextSupportsOpenGL32(true);
}
else
// fallback on old approach
if (!this->ContextId)
{
this->ContextId = wglCreateContext(hDC);
}
......@@ -1403,198 +1395,29 @@ void vtkWin32OpenGLRenderWindow::SetOffScreenRendering(int offscreen)
int size[2];
size[0] = (this->Size[0] > 0) ? this->Size[0] : 300;
size[1] = (this->Size[1] > 0) ? this->Size[1] : 300;
this->SaveScreenRendering();
this->CreateOffScreenWindow(size[0],size[1]);
}
else
{
this->CleanUpOffScreenRendering();
if (!this->WindowId)
{
this->WindowInitialize();
this->OpenGLInit();
if (this->Interactor)
{
this->Interactor->ReInitialize();
}
this->DoubleBuffer = 1;
}
else
{
this->ResumeScreenRendering();
}
}
}
void vtkWin32OpenGLRenderWindow::SaveScreenRendering()
{
this->ScreenMapped = this->Mapped;
this->ScreenWindowSize[0] = this->Size[0];
this->ScreenWindowSize[1] = this->Size[1];
this->ScreenDeviceContext = this->DeviceContext;
this->ScreenDoubleBuffer = this->DoubleBuffer;
this->ScreenContextId = this->ContextId;
}
void vtkWin32OpenGLRenderWindow::CreateOffScreenWindow(int width,
int height)
{
int status = this->CreatingOffScreenWindow;
this->CreatingOffScreenWindow = 1;
if(!this->CreateHardwareOffScreenWindow(width,height))
{
#ifdef UNICODE
HDC dc = CreateDC(L"DISPLAY", 0, 0, 0);
#else
HDC dc = CreateDC("DISPLAY", 0, 0, 0);
#endif
this->CreateOffScreenDC(width,height,dc);
DeleteDC(dc);
}
this->CreateHardwareOffScreenWindow(width,height);
this->CreatingOffScreenWindow = status;
}
void vtkWin32OpenGLRenderWindow::CreateOffScreenDC(int xsize, int ysize,
HDC aHdc)
{
int dataWidth = ((xsize*3+3)/4)*4;
this->MemoryDataHeader.bmiHeader.biSize = 40;
this->MemoryDataHeader.bmiHeader.biWidth = xsize;
this->MemoryDataHeader.bmiHeader.biHeight = ysize;
this->MemoryDataHeader.bmiHeader.biPlanes = 1;
this->MemoryDataHeader.bmiHeader.biBitCount = 24;
this->MemoryDataHeader.bmiHeader.biCompression = BI_RGB;
this->MemoryDataHeader.bmiHeader.biClrUsed = 0;
this->MemoryDataHeader.bmiHeader.biClrImportant = 0;
this->MemoryDataHeader.bmiHeader.biSizeImage = dataWidth*ysize;
this->MemoryDataHeader.bmiHeader.biXPelsPerMeter = 10000;
this->MemoryDataHeader.bmiHeader.biYPelsPerMeter = 10000;
HBITMAP dib = CreateDIBSection(aHdc,
&this->MemoryDataHeader, DIB_RGB_COLORS,
(void **)(&(this->MemoryData)), NULL, 0);
SIZE oldSize;
SetBitmapDimensionEx(dib, xsize, ysize, &oldSize);
// try using a DIBsection
this->CreateOffScreenDC(dib, aHdc);
}
void vtkWin32OpenGLRenderWindow::CreateOffScreenDC(HBITMAP hbmp, HDC aHdc)
{
this->InitializeApplication();
this->VTKRegisterClass();
BITMAP bm;
GetObject(hbmp, sizeof(BITMAP), &bm);
this->MemoryBuffer = hbmp;
// Create a compatible device context
this->MemoryHdc = (HDC)CreateCompatibleDC(aHdc);
// Put the bitmap into the device context
SelectObject(this->MemoryHdc, this->MemoryBuffer);
this->ReleaseGraphicsResources(this);
// adjust settings for renderwindow
this->Mapped =0;
this->Size[0] = bm.bmWidth;
this->Size[1] = bm.bmHeight;
this->DeviceContext = this->MemoryHdc;
this->DoubleBuffer = 0;
this->SetupPixelFormatPaletteAndContext(this->DeviceContext,
PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI |
PFD_DRAW_TO_BITMAP, this->GetDebug(), 24, 32);
this->MakeCurrent();
this->OpenGLInit();
}
void vtkWin32OpenGLRenderWindow::SetupMemoryRendering(int xsize, int ysize,
HDC aHdc)
{
// save the current state
this->ScreenMapped = this->Mapped;
this->ScreenWindowSize[0] = this->Size[0];
this->ScreenWindowSize[1] = this->Size[1];
this->ScreenDeviceContext = this->DeviceContext;
this->ScreenDoubleBuffer = this->DoubleBuffer;
this->ScreenContextId = this->ContextId;
this->CreateOffScreenDC(xsize, ysize, aHdc);
}
void vtkWin32OpenGLRenderWindow::SetupMemoryRendering(HBITMAP hbmp)
{
#ifdef UNICODE
HDC dc = CreateDC(L"DISPLAY", 0, 0, 0);
#else
HDC dc = CreateDC("DISPLAY", 0, 0, 0);
#endif
// save the current state
this->ScreenMapped = this->Mapped;
this->ScreenWindowSize[0] = this->Size[0];
this->ScreenWindowSize[1] = this->Size[1];
this->ScreenDeviceContext = this->DeviceContext;
this->ScreenDoubleBuffer = this->DoubleBuffer;
this->ScreenContextId = this->ContextId;
this->CreateOffScreenDC(hbmp, dc);
DeleteDC(dc);
}
HDC vtkWin32OpenGLRenderWindow::GetMemoryDC()
{
return this->MemoryHdc;
}
void vtkWin32OpenGLRenderWindow::CleanUpOffScreenRendering(void)
{
if(this->OffScreenUseFrameBuffer)
{
this->DestroyHardwareOffScreenWindow();
}
else
{
if (!this->MemoryHdc)
{
return;
}
GdiFlush();
// we need to release resources
this->CleanUpRenderers();
DeleteDC(this->MemoryHdc);
this->MemoryHdc = (HDC)0;
DeleteObject(this->MemoryBuffer);
if (wglDeleteContext(this->ContextId) != TRUE)
{
vtkErrorMacro("wglDeleteContext failed in CleanUpOffScreenRendering(), error: " << GetLastError());
}
this->ContextId=0;
}
}
void vtkWin32OpenGLRenderWindow::ResumeScreenRendering(void)
{
// release OpenGL graphics resources before switch back to on-screen.
if(this->ContextId!=0)
{
this->MakeCurrent();
this->ReleaseGraphicsResources(this);
}
this->Mapped = this->ScreenMapped;
this->Size[0] = this->ScreenWindowSize[0];
this->Size[1] = this->ScreenWindowSize[1];
this->DeviceContext = this->ScreenDeviceContext;
this->DoubleBuffer = this->ScreenDoubleBuffer;
this->ContextId = this->ScreenContextId;
this->MakeCurrent();
}
//----------------------------------------------------------------------------
......
......@@ -183,16 +183,6 @@ public:
// This is a useful check to abort a long render.
virtual int GetEventPending();
// Description:
// These methods can be used by MFC applications
// to support print preview and printing, or more
// general rendering into memory.
void SetupMemoryRendering(int x, int y, HDC prn);
void SetupMemoryRendering(HBITMAP hbmp);
void ResumeScreenRendering(void);
HDC GetMemoryDC();
unsigned char *GetMemoryData(){return this->MemoryData;};
// Description:
// Initialize OpenGL for this window.
virtual void SetupPalette(HDC hDC);
......@@ -240,18 +230,6 @@ protected:
int OwnWindow;
int ScreenSize[2];
// the following is used to support rendering into memory
BITMAPINFO MemoryDataHeader;
HBITMAP MemoryBuffer;
unsigned char *MemoryData; // the data in the DIBSection
HDC MemoryHdc;
int ScreenMapped;
int ScreenWindowSize[2];
HDC ScreenDeviceContext;
int ScreenDoubleBuffer;
HGLRC ScreenContextId;
int CreatingOffScreenWindow; // to avoid recursion (and memory leaks...)
// message handler
......@@ -270,10 +248,7 @@ protected:
virtual void DestroyWindow();
void InitializeApplication();
void CleanUpOffScreenRendering(void);
void CreateOffScreenDC(int xsize, int ysize, HDC aHdc);
void CreateOffScreenDC(HBITMAP hbmp, HDC aHdc);
void CreateOffScreenWindow(int width,int height);
void SaveScreenRendering();
void CleanUpRenderers();
void VTKRegisterClass();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment