Turned GLRenderer::pixelCapture to GLRenderer::screenCapture() which encapsulates screen capturing properly and returns a ready image.

Thu, 23 Feb 2017 23:29:16 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 23 Feb 2017 23:29:16 +0200
changeset 1171
430ffa371d2a
parent 1170
2045a395213a
child 1172
3defab8cfd93

Turned GLRenderer::pixelCapture to GLRenderer::screenCapture() which encapsulates screen capturing properly and returns a ready image.

src/glrenderer.cpp file | annotate | diff | comparison | revisions
src/glrenderer.h file | annotate | diff | comparison | revisions
src/toolsets/viewtoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/glrenderer.cpp	Thu Feb 23 23:17:10 2017 +0200
+++ b/src/glrenderer.cpp	Thu Feb 23 23:29:16 2017 +0200
@@ -805,17 +805,21 @@
 		m_objectAtCursor = nullptr;
 }
 
-// =============================================================================
-//
-QByteArray GLRenderer::capturePixels()
+/*
+ * Returns an image containing the current render of the scene.
+ */
+QImage GLRenderer::screenCapture()
 {
-	QByteArray result;
-	result.resize (4 * width() * height());
-	m_takingScreenCapture = true;
-	update(); // Smile!
-	m_takingScreenCapture = false;
-	glReadPixels(0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_BYTE, result.data());
-	return result;
+	// Read the current render to a buffer of pixels. We use RGBA format even though the image should be fully opaque at all times.
+	// This is because apparently GL_RGBA/GL_UNSIGNED_BYTE is the only setting pair that is guaranteed to actually work!
+	// ref: https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glReadPixels.xml
+	QByteArray pixelData;
+	pixelData.resize(4 * width() * height());
+	glReadPixels(0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
+
+	// Prepare the image and return it. It appears that GL and Qt formats have red and blue swapped and the Y axis flipped.
+	QImage image {reinterpret_cast<const uchar*>(pixelData.constData()), width(), height(), QImage::Format_ARGB32};
+	return image.rgbSwapped().mirrored();
 }
 
 /*
--- a/src/glrenderer.h	Thu Feb 23 23:17:10 2017 +0200
+++ b/src/glrenderer.h	Thu Feb 23 23:29:16 2017 +0200
@@ -78,7 +78,6 @@
 	~GLRenderer();
 
 	Camera camera() const;
-	QByteArray capturePixels();
 	GLCamera& currentCamera();
 	const GLCamera& currentCamera() const;
 	Qt::KeyboardModifiers keyboardModifiers() const;
@@ -90,6 +89,7 @@
 	LDObject* pick(int mouseX, int mouseY);
 	void resetAllAngles();
 	void resetAngles();
+	QImage screenCapture();
 	void setBackground();
 	void setCamera(Camera cam);
 	QPen textPen() const;
@@ -145,7 +145,6 @@
 	QGenericMatrix<4, 4, GLfloat> m_rotationMatrix;
 	GLCamera m_cameras[7];
 	bool m_useDarkBackground = false;
-	bool m_takingScreenCapture = false;
 	bool m_panning = false;
 	bool m_initialized = false;
 	bool m_isDrawingSelectionScene = false;
--- a/src/toolsets/viewtoolset.cpp	Thu Feb 23 23:17:10 2017 +0200
+++ b/src/toolsets/viewtoolset.cpp	Thu Feb 23 23:29:16 2017 +0200
@@ -104,21 +104,16 @@
 
 void ViewToolset::screenshot()
 {
-	const char* imageformats = "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;"
-		"PPM images (*.ppm);;X11 Bitmaps (*.xbm);;X11 Pixmaps (*.xpm);;All Files (*.*)";
-	int width = m_window->renderer()->width();
-	int height = m_window->renderer()->height();
-	QByteArray capture = m_window->renderer()->capturePixels();
-	const uchar* imagedata = reinterpret_cast<const uchar*> (capture.constData());
-	// GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well.
-	QImage image = QImage (imagedata, width, height, QImage::Format_ARGB32).rgbSwapped().mirrored();
+	const char* imageFormats = "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;"
+	    "PPM images (*.ppm);;X11 Bitmaps (*.xbm);;X11 Pixmaps (*.xpm);;All Files (*.*)";
+	QImage image = m_window->renderer()->screenCapture();
 	QString root = Basename (currentDocument()->name());
 
 	if (root.right (4) == ".dat")
 		root.chop (4);
 
 	QString defaultname = (not root.isEmpty()) ? format ("%1.png", root) : "";
-	QString filename = QFileDialog::getSaveFileName (m_window, "Save Screencap", defaultname, imageformats);
+	QString filename = QFileDialog::getSaveFileName (m_window, "Save Screencap", defaultname, imageFormats);
 
 	if (not filename.isEmpty() and not image.save (filename))
 	{

mercurial