-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Screenshot Command #98
base: master
Are you sure you want to change the base?
Changes from all commits
234728b
2080915
6ba7031
b9ddb49
699dcb3
48251e3
6cd8303
4066eef
4fda63e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
build | ||
./data | ||
gh-pages | ||
*.swp |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
#include <QItemSelectionModel> | ||
#include <QMessageBox> | ||
#include <QGLFormat> | ||
#include <QOpenGLFramebufferObject> | ||
|
||
#include "config.h" | ||
#include "fileloader.h" | ||
|
@@ -309,8 +310,7 @@ void View3D::initializeGL() | |
setFocus(); | ||
} | ||
|
||
|
||
void View3D::resizeGL(int w, int h) | ||
void View3D::resizeViewport(int w, int h) | ||
{ | ||
//Note: This function receives "device pixel sizes" for correct OpenGL viewport setup | ||
// Under OS X with retina display, this becomes important as it is 2x the width() or height() | ||
|
@@ -325,6 +325,14 @@ void View3D::resizeGL(int w, int h) | |
double dPR = getDevicePixelRatio(); | ||
|
||
m_camera.setViewport(QRect(0,0,double(w)/dPR,double(h)/dPR)); | ||
} | ||
|
||
void View3D::resizeGL(int w, int h) | ||
{ | ||
if (m_badOpenGL) | ||
return; | ||
|
||
resizeViewport(w, h); | ||
|
||
m_incrementalFramebuffer = allocIncrementalFramebuffer(w,h); | ||
|
||
|
@@ -372,6 +380,23 @@ unsigned int View3D::allocIncrementalFramebuffer(int w, int h) const | |
return fb; | ||
} | ||
|
||
void View3D::clearBuffers() const | ||
{ | ||
glClearDepth(1.0f); | ||
glEnable(GL_DEPTH_TEST); | ||
glDepthFunc(GL_LEQUAL); | ||
glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(), | ||
m_backgroundColor.blueF(), 1.0f); | ||
if (!m_incrementalDraw) | ||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
} | ||
|
||
TransformState View3D::makeTransformState(int w, int h) const | ||
{ | ||
return TransformState(Imath::V2i(w, h), | ||
m_camera.projectionMatrix(), | ||
m_camera.viewMatrix()); | ||
} | ||
|
||
void View3D::paintGL() | ||
{ | ||
|
@@ -397,18 +422,9 @@ void View3D::paintGL() | |
|
||
//-------------------------------------------------- | ||
// Draw main scene | ||
TransformState transState(Imath::V2i(w, h), | ||
m_camera.projectionMatrix(), | ||
m_camera.viewMatrix()); | ||
|
||
glClearDepth(1.0f); | ||
glEnable(GL_DEPTH_TEST); | ||
glDepthFunc(GL_LEQUAL); | ||
glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(), | ||
m_backgroundColor.blueF(), 1.0f); | ||
if (!m_incrementalDraw) | ||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
TransformState transState = makeTransformState(w, h); | ||
|
||
clearBuffers(); | ||
std::vector<const Geometry*> geoms = selectedGeometry(); | ||
|
||
// Draw bounding boxes | ||
|
@@ -498,6 +514,42 @@ void View3D::paintGL() | |
glCheckError(); | ||
} | ||
|
||
|
||
QImage View3D::renderScreenShot(int width, int height) | ||
{ | ||
if (m_badOpenGL) | ||
return QImage(); | ||
|
||
double dPR = getDevicePixelRatio(); | ||
if (width < 0) | ||
width = this->width(); | ||
|
||
if (height < 0) | ||
height = this->height(); | ||
|
||
// Note: the reason for the following two lines and the subsequent downsampling of the | ||
// resulting image is to make the radius of rendered points consistent between the | ||
// gui and screenshot on displas with dPR != 1. | ||
width *= dPR; | ||
height *= dPR; | ||
|
||
QOpenGLFramebufferObject framebuffer(QSize(width, height), QOpenGLFramebufferObject::Depth); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class is Qt5 only, so we'd be breaking with Qt4 compatibility by using this. I guess let's get it all working, and then I'll need to decide. (TBH, I'm kinda keen to give up on Qt4 because the number of different OpenGL and OS versions is already enough to be a real drag on limited development resources...) |
||
framebuffer.bind(); | ||
resizeViewport(width, height); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ends up calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason for scaling up the offscreen buffer by dPR and subsequently downscaling the resulting image by the same factor was just a workaround to make points rendered into the offscreen buffer the same size as points in the gui when rendered on my Retina Macbook (dPR=2). If rendering to the offscreen buffer at the same resolution as the gui window, the points in the screenshot end up being twice as large as those on the screen. I made a short attempt at figuring out exactly why this was happening but had to get on with other things. Any idea why this would happen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, of course! The problem here is that in the vertex shader prog.setUniformValue("pointPixelScale", (GLfloat)(0.5*transState.viewSize.x*transState.projMatrix[0][0])); |
||
clearBuffers(); | ||
|
||
// Render points only | ||
drawPoints(makeTransformState(width, height), | ||
selectedGeometry(), | ||
DBL_MAX, | ||
false); | ||
glFinish(); | ||
|
||
QImage img = framebuffer.toImage(); | ||
return img.scaledToWidth(width / dPR, Qt::SmoothTransformation); | ||
} | ||
|
||
|
||
void View3D::drawMeshes(const TransformState& transState, | ||
const std::vector<const Geometry*>& geoms) const | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand things, this shouldn't be required, as
getDevicePixelRatio()
is related to the physical screen, not an offscreen buffer.Instead, I'd suggest explicitly antialiasing, either by using
QOpenGLFramebufferObjectFormat
, or possibly more portably by just using a multiple of the actual width and height and downsampling on the CPU side (as you already have below withscaleToWidth()
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is, just keep what we have, but get
dPR
from a setting or a fixed supersampling (eg, dPR = 2). Probably want to rename it as such.