我將複雜的2D場景繪製到OpenGL窗口。我希望用戶能夠截取場景並將其保存爲JPG格式。但是,我希望他們能夠指定場景可以比他們的屏幕更大(這將允許他們看到更多細節等)。向C#位圖繪製一個OpenGL場景;屏幕截屏
當它們指定大於符合其屏幕的視口的數字時,它們無法看到的所有內容都不會被繪製到位圖上。我覺得我對這些OpenGL函數的行爲有些誤解,而這些函數是我無法追蹤的。
下面的代碼在renderSize
小於默認視口,我開始使用該程序時完全正常。如果renderSize
較大,則會創建適當大小的JPG,但是通過屏幕可見區域的右側/頂部僅爲空白。如果我在第二臺顯示器上點擊並拖動我的視口,那麼更多的圖片會被繪製,但如果renderSize
比兩臺顯示器都大,仍然不是全部。我怎樣才能使這個繪圖獨立於顯示在屏幕上的視口?
(我可以驗證renderLocation
和renderSize
設置是否正確時,這個函數被調用,以renderSize
是一些大的數字,比如7000×2000個)
public Bitmap renderToBitmap(RenderMode mode)
{
// load a specific ortho projection that will contain the entire graph
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
GL.LoadIdentity();
GL.Ortho(0, renderSize.Width, 0, renderSize.Height, -1, 1);
GL.Viewport(0, 0, renderSize.Width, renderSize.Height);
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix();
GL.LoadIdentity();
// move the graph so it starts drawing at 0, 0 and fills the entire viewport
GL.Translate(-renderLocation.X, -renderLocation.Y, 0);
GL.ClearColor(Color.White);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// render the graph
this.render(mode);
// set up bitmap we will save to
Bitmap bitmap = new Bitmap(renderSize.Width, renderSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
// read the data directly into the bitmap's buffer (bitmap is stored in BGRA)
GL.ReadPixels(0, 0, renderSize.Width, renderSize.Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bData.Scan0);
bitmap.UnlockBits(bData);
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); // compensate for openGL/GDI y-coordinates being flipped
// revert the stuff about openGL we changed
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Modelview);
GL.PopMatrix();
return bitmap;
}
這裏就是我如何初始化我的GL窗口中,案例發揮作用。
private void initGL()
{
GL.ClearColor(Color.AntiqueWhite);
GL.Disable(EnableCap.Lighting);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
resetCamera();
}
private void resetCamera()
{
offsetX = offsetY = 0; // Bottom-left corner pixel has coordinate (0, 0)
zoomFactor = 1;
setupViewport();
glWindow.Invalidate();
}
private void setupViewport()
{
int w = glWindow.Width;
int h = glWindow.Height;
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(0 + offsetX, w + offsetX, 0 + offsetY, h + offsetY, -1, 1);
GL.Viewport(0, 0, w, h); // Use all of the glControl painting area
}
謝謝,這似乎是問題。我編寫了我自己的平鋪算法(類似於libtr)來克服這個問題,將場景渲染成多個視口大小的位圖,然後將它們全部繪製成一個大的位圖。 – XenoScholar 2013-02-20 20:34:10