A 'standard' Camera with fixed near and far planes.
A new StandardCamera
class is derived from Camera
.
Its near and far planes distances are set to fixed values (instead of being fit to
scene dimensions as is done in the QGLViewer::Camera
).
The orthographic frustum dimensions are fixed instead of depending on the distance
to the pivotPoint()
. Since this may be needed for some applications,
you may want to use this standardCamera
class in your code.
#include <QGLViewer/camera.h> class StandardCamera : public qglviewer::Camera { public: StandardCamera(); virtual qreal zNear() const; virtual qreal zFar() const; void toggleMode() { standard = !standard; } bool isStandard() { return standard; } void changeOrthoFrustumSize(int delta); virtual void getOrthoWidthHeight(GLdouble &halfWidth, GLdouble &halfHeight) const; private: bool standard; float orthoSize; };
#include "standardCamera.h" #include <QWheelEvent> using namespace qglviewer; StandardCamera::StandardCamera() { standard = true; orthoSize = 1.0; } qreal StandardCamera::zNear() const { if (standard) return 0.001; else return Camera::zNear(); } qreal StandardCamera::zFar() const { if (standard) return 1000.0; else return Camera::zFar(); } void StandardCamera::changeOrthoFrustumSize(int delta) { if (delta > 0) orthoSize *= 1.1; else orthoSize /= 1.1; } void StandardCamera::getOrthoWidthHeight(GLdouble &halfWidth, GLdouble &halfHeight) const { if (standard) { halfHeight = orthoSize; halfWidth = aspectRatio() * orthoSize; } else Camera::getOrthoWidthHeight(halfWidth, halfHeight); }
#include <QGLViewer/qglviewer.h> class CameraViewer : public QGLViewer { public: CameraViewer(qglviewer::Camera *camera); protected: virtual void draw(); virtual void init(); private: qglviewer::Camera *c; };
#include <QGLViewer/qglviewer.h> class StandardCamera; class Viewer : public QGLViewer { Q_OBJECT public: Viewer(StandardCamera *camera); public: Q_SIGNALS: void cameraChanged(); protected: virtual void draw(); virtual void init(); virtual QString helpString() const; virtual void keyPressEvent(QKeyEvent *e); virtual void wheelEvent(QWheelEvent *e); private: void showMessage(); };
#include "cameraViewer.h" using namespace qglviewer; CameraViewer::CameraViewer(Camera *camera) : c(camera){}; void CameraViewer::draw() { // Exactly the same draw than for 'Viewer'. The two viewers could also share a // 'Scene' instance. const float nbSteps = 200.0; glBegin(GL_QUAD_STRIP); for (int i = 0; i < nbSteps; ++i) { const float ratio = i / nbSteps; const float angle = 21.0 * ratio; const float c = cos(angle); const float s = sin(angle); const float r1 = 1.0 - 0.8f * ratio; const float r2 = 0.8f - 0.8f * ratio; const float alt = ratio - 0.5f; const float nor = 0.5f; const float up = sqrt(1.0 - nor * nor); glColor3f(1.0 - ratio, 0.2f, ratio); glNormal3f(nor * c, up, nor * s); glVertex3f(r1 * c, alt, r1 * s); glVertex3f(r2 * c, alt + 0.05f, r2 * s); } glEnd(); // Draws the other viewer's camera glDisable(GL_LIGHTING); glLineWidth(4.0); glColor4f(1.0, 1.0, 1.0, 0.5); c->draw(); glEnable(GL_LIGHTING); } void CameraViewer::init() { // Places the cameraViewer's camera far away in order to see the (other // viewer) camera. if (!restoreStateFromFile()) { // Make near and far planes much further from scene in order not to clip c's // display. camera()->setZClippingCoefficient(50.0); camera()->setViewDirection(qglviewer::Vec(0.0, -1.0, 0.0)); showEntireScene(); } // Enable semi-transparent culling planes glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
#include "cameraViewer.h" #include "standardCamera.h" #include "viewer.h" #include <QApplication> #include <QGLViewer/manipulatedCameraFrame.h> int main(int argc, char **argv) { QApplication application(argc, argv); // Instantiate the two viewers. StandardCamera *sc = new StandardCamera(); Viewer viewer(sc); CameraViewer cviewer(sc); // Make sure every v camera movement updates the camera viewer QObject::connect(viewer.camera()->frame(), SIGNAL(manipulated()), &cviewer, SLOT(updateGL())); QObject::connect(viewer.camera()->frame(), SIGNAL(spun()), &cviewer, SLOT(updateGL())); // Also update on camera change (type or mode) QObject::connect(&viewer, SIGNAL(cameraChanged()), &cviewer, SLOT(updateGL())); viewer.setWindowTitle("standardCamera"); cviewer.setWindowTitle("Camera viewer"); cviewer.show(); viewer.show(); return application.exec(); }
#include "viewer.h" #include "standardCamera.h" #include <QKeyEvent> #if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) #define MidButton MiddleButton #endif using namespace std; using namespace qglviewer; Viewer::Viewer(StandardCamera *nfc) { // Change the camera. Camera *c = camera(); setCamera(nfc); delete c; } // Draws a spiral void Viewer::draw() { const float nbSteps = 200.0; glBegin(GL_QUAD_STRIP); for (int i = 0; i < nbSteps; ++i) { const float ratio = i / nbSteps; const float angle = 21.0 * ratio; const float c = cos(angle); const float s = sin(angle); const float r1 = 1.0 - 0.8f * ratio; const float r2 = 0.8f - 0.8f * ratio; const float alt = ratio - 0.5f; const float nor = 0.5f; const float up = sqrt(1.0 - nor * nor); glColor3f(1.0 - ratio, 0.2f, ratio); glNormal3f(nor * c, up, nor * s); glVertex3f(r1 * c, alt, r1 * s); glVertex3f(r2 * c, alt + 0.05f, r2 * s); } glEnd(); } void Viewer::init() { // Restore previous viewer state. if (!restoreStateFromFile()) showEntireScene(); setKeyDescription(Qt::Key_T, "Toggles camera type (perspective or orthographic)"); setKeyDescription(Qt::Key_M, "Toggles camera mode (standard or QGLViewer)"); setMouseBindingDescription( Qt::ShiftModifier, Qt::MidButton, "Change frustum size (for standard camera in orthographic mode)"); // Display help window. help(); } void Viewer::showMessage() { QString std = ((StandardCamera *)camera())->isStandard() ? "Standard camera" : "QGLViewer camera"; QString type = camera()->type() == Camera::PERSPECTIVE ? "Perspective" : "Orthographic"; displayMessage(std + " - " + type); Q_EMIT cameraChanged(); } void Viewer::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_M) { // 'M' changes mode : standard or QGLViewer camera ((StandardCamera *)camera())->toggleMode(); showMessage(); } else if (e->key() == Qt::Key_T) { // 'T' changes the projection type : perspective or orthogonal if (camera()->type() == Camera::ORTHOGRAPHIC) camera()->setType(Camera::PERSPECTIVE); else camera()->setType(Camera::ORTHOGRAPHIC); showMessage(); } else QGLViewer::keyPressEvent(e); } void Viewer::wheelEvent(QWheelEvent *e) { if ((camera()->type() == Camera::ORTHOGRAPHIC) && (((StandardCamera *)camera())->isStandard()) && (e->modifiers() & Qt::ShiftModifier)) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) ((StandardCamera *)camera())->changeOrthoFrustumSize(e->delta()); #else ((StandardCamera *)camera())->changeOrthoFrustumSize(e->angleDelta().y()); #endif Q_EMIT cameraChanged(); update(); } else QGLViewer::wheelEvent(e); } QString Viewer::helpString() const { QString text("<h2>S t a n d a r d C a m e r a</h2>"); text += "An overloaded <code>Camera</code> class is used, that reproduces " "the 'standard' OpenGL settings.<br><br>"; text += "With this camera, the near and (resp. far) plane distance is set to " "a very small (resp. very large) value. "; text += "With the orthographic camera type, the frustum dimensions are " "fixed. Use <code>Shift</code> and the mouse wheel to change " "them.<br><br>"; text += "On the other hand, the QGLViewer camera fits the near and far " "distances to the scene radius. "; text += "Fine tuning is available using <code>zClippingCoefficient()</code> " "and <code>zNearCoefficient()</code>. "; text += "However, visual results do not seem to be impacted by this zBuffer " "fitted range.<br><br>"; text += "The QGLViewer camera also adapts the orthographic frustum " "dimensions to the distance to the <code>pivotPoint()</code> to " "mimic a perspective camera. "; text += "Since this behavior may not be needed, this example shows how to " "override it.<br><br>"; text += "The second viewer displays the first one's camera to show its " "configuration.<br><br>"; text += "Use <b>M</b> to switch between 'standard' and QGLViewer camera " "behavior.<br>"; text += "Use <b>T</b> to switch between perspective and orthographic camera " "type.<br><br>"; text += "Use <b>Shift+wheel</b> to change standard camera orthographic size."; return text; }
Back to the examples main page.