⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 view3d.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
字号:
/******************************************************************************** Copyright (C) 2005-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <QtCore>#include <QtGui>#include <QtOpenGL>#include "abstractformeditor.h"#include "abstractmetadatabase.h"#include "abstractformwindow.h"#include "view3d.h"#define SELECTION_BUFSIZE 512/********************************************************************************* QView3DWidget*/class QView3DWidget : public QGLWidget{    Q_OBJECTpublic:    QView3DWidget(QWidget *parent);    virtual void initializeGL();    virtual void resizeGL(int w, int h);    virtual void paintGL();    void clear();    void addTexture(QWidget *w, const QPixmap &pm);    void beginAddingWidgets(QWidget *form);    void addWidget(int depth, QWidget *w);    void endAddingWidgets();    QWidget *widgetAt(const QPoint &pos);signals:    void updateForm();protected:    void mousePressEvent(QMouseEvent *);    void mouseReleaseEvent(QMouseEvent *);    void mouseMoveEvent(QMouseEvent *);    void wheelEvent(QWheelEvent *);    void keyReleaseEvent(QKeyEvent *);    void contextMenuEvent(QContextMenuEvent *);private:    QWidget *m_form;    QPoint m_old_pos;    bool m_layer_coloring;    bool m_use_mipmaps;    GLuint m_form_list_id;    typedef QMap<QWidget*, GLuint> TextureMap;    TextureMap m_texture_map;    typedef QMap<GLuint, QWidget*> WidgetNameMap;    GLuint m_next_widget_name;    WidgetNameMap m_widget_name_map;};QView3DWidget::QView3DWidget(QWidget *parent)    : QGLWidget(parent)    , m_layer_coloring(true)    , m_form_list_id(0)    , m_next_widget_name(0){    setFocusPolicy(Qt::StrongFocus);}static int nearestSize(int v){    int n = 0, last = 0;    for (int s = 0; s < 32; ++s) {        if (((v>>s) & 1) == 1) {            ++n;            last = s;        }    }    if (n > 1)        return 1 << (last+1);    return 1 << last;}// static int pm_cnt = 0;void QView3DWidget::addTexture(QWidget *w, const QPixmap &pm){    int tx_w = nearestSize(pm.width());    int tx_h = nearestSize(pm.height());    QPixmap tmp(tx_w, tx_h);    tmp.fill(QColor(0,0,0));    QPainter p(&tmp);    p.drawPixmap(0, tx_h - pm.height(), pm);    p.end();    QImage tex = tmp.toImage();//    QString file_name = QString("pixmapDump%1.png").arg(pm_cnt++);//    qDebug() << "grabWidget():" << file_name << tex.save(file_name, "PNG");    tex = QGLWidget::convertToGLFormat(tex);    GLuint tx_id;    glGenTextures(1, &tx_id);    glBindTexture(GL_TEXTURE_2D, tx_id);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    if (m_use_mipmaps) {        //glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);        //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.f);    } else {        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    }    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex.width(), tex.height(), 0, GL_RGBA,                GL_UNSIGNED_BYTE, tex.bits());    m_texture_map[w] = tx_id;}void QView3DWidget::addWidget(int depth, QWidget *widget){    TextureMap::const_iterator it = m_texture_map.find(widget);    Q_ASSERT(it != m_texture_map.end());    makeCurrent();    int w = m_form->size().width();    int h = m_form->size().height();    int max = qMax(w, h);    QRect r = widget->rect();    QPoint pos = widget->mapToGlobal(QPoint(0, 0));    r.moveTopLeft(m_form->mapFromGlobal(pos));    float s = r.width()/float(nearestSize(r.width()));    float t = r.height()/float(nearestSize(r.height()));    if (m_layer_coloring)        glColor4f(1.0 - depth/10.0, 1.0 - depth/10.0, 1.0, 1.0 - depth/20.0);    else        glColor4f(1.0, 1.0, 1.0, 1.0);    glBindTexture(GL_TEXTURE_2D, *it);    glBegin(GL_QUADS);    glLoadName(m_next_widget_name);    glTexCoord2f(0.0, 0.0); glVertex3f(r.left() - w/2, r.bottom() - h/2, depth*max/8);    glTexCoord2f(s, 0.0);   glVertex3f(r.right() - w/2, r.bottom()- h/2, depth*max/8);    glTexCoord2f(s, t);     glVertex3f(r.right() - w/2, r.top() - h/2, depth*max/8);    glTexCoord2f(0.0, t);   glVertex3f(r.left() - w/2, r.top() - h/2, depth*max/8);    glEnd();    m_widget_name_map[m_next_widget_name++] = widget;}void QView3DWidget::clear(){    makeCurrent();    glDeleteLists(m_form_list_id, 1);    foreach (GLuint id, m_texture_map)        glDeleteTextures(1, &id);    m_texture_map.clear();    m_widget_name_map.clear();    m_next_widget_name = 0;}void QView3DWidget::beginAddingWidgets(QWidget *form){    makeCurrent();    m_form = form;    m_form_list_id = glGenLists(1);    glNewList(m_form_list_id, GL_COMPILE);    glInitNames();    glPushName(-1);    m_next_widget_name = 0;}void QView3DWidget::endAddingWidgets(){    makeCurrent();    glEndList();}void QView3DWidget::initializeGL(){    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    qglClearColor(palette().color(QPalette::Background).dark());    glColor3f (1.0, 1.0, 1.0);    glEnable(GL_DEPTH_TEST);    glDepthFunc(GL_LEQUAL);    glShadeModel(GL_FLAT);    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    QString extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));    m_use_mipmaps = false;//  extensions.contains("GL_SGIS_generate_mipmap");}void QView3DWidget::resizeGL(int width, int height){    glViewport(0, 0, width, height);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    glOrtho(-width/2, width/2, height/2, -height/2, -999999, 999999);}void QView3DWidget::paintGL(){    glColor4f(1.0, 1.0, 1.0, 1.0);    glEnable(GL_TEXTURE_2D);    glEnable(GL_BLEND);    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glCallList(m_form_list_id);    glPushAttrib(GL_ENABLE_BIT);    glDisable(GL_DEPTH_TEST);    glDisable(GL_LIGHTING);    glDisable(GL_TEXTURE_2D);    glMatrixMode(GL_MODELVIEW);    glPushMatrix();    glLoadIdentity();    glTranslatef(-width()/2, -height()/2, 0.0);    QFontMetrics fm(font());    glColor4f(0.4, 0.4, 0.4, 0.7);    glRecti(0, height() - fm.lineSpacing()*2.5, width(), height());    glColor3f(1.0, 1.0, 1.0);    renderText(10, height() - fm.lineSpacing()*1.5,               "Press and hold left/right mouse button = tilt the view.");    renderText(10, height() - fm.lineSpacing()*0.5,               "Mouse wheel = zoom. 't' = toggle layer coloring. 'r' = reset transform.");    glPopMatrix();    glPopAttrib();}QWidget *QView3DWidget::widgetAt(const QPoint &pos){    makeCurrent();    GLuint selectBuf[SELECTION_BUFSIZE];    glSelectBuffer(SELECTION_BUFSIZE, selectBuf);    glRenderMode (GL_SELECT);    glMatrixMode(GL_PROJECTION);    glPushMatrix();    glLoadIdentity();    glCallList(m_form_list_id);    return 0;}void QView3DWidget::keyReleaseEvent(QKeyEvent *e){    if (e->key() == Qt::Key_T) {        m_layer_coloring = !m_layer_coloring;        emit updateForm();    } else if (e->key() == Qt::Key_R) {        makeCurrent();        glMatrixMode(GL_MODELVIEW);        glLoadIdentity();    }    updateGL();}void QView3DWidget::mousePressEvent(QMouseEvent *e){    m_old_pos = e->pos();}void QView3DWidget::mouseReleaseEvent(QMouseEvent *e){    m_old_pos = e->pos();}void QView3DWidget::mouseMoveEvent(QMouseEvent *e){    if (e->buttons() & (Qt::LeftButton | Qt::RightButton)) {        GLfloat rx = (GLfloat) (e->x() - m_old_pos.x()) / width();        GLfloat ry = (GLfloat) (e->y() - m_old_pos.y()) / height();        makeCurrent();        glMatrixMode(GL_MODELVIEW);        if (e->buttons() & Qt::LeftButton) {            // Left button down - rotate around X and Y axes            glRotatef(-180*ry, 1, 0, 0);            glRotatef(180*rx, 0, 1, 0);        } else if (e->buttons() & Qt::RightButton) {            // Right button down - rotate around X and Z axes            glRotatef(-180*ry, 1, 0, 0);            glRotatef(-180*rx, 0, 0, 1);        }        updateGL();        m_old_pos = e->pos();    } else {    }}void QView3DWidget::wheelEvent(QWheelEvent *e){    makeCurrent();    glMatrixMode(GL_MODELVIEW);    if (e->delta() < 0)        glScalef(0.9, 0.9, 0.9);    else        glScalef(1.1, 1.1, 1.1);    updateGL();}void QView3DWidget::contextMenuEvent(QContextMenuEvent *e){    e->accept();}/********************************************************************************* Misc tools*/class WalkWidgetTreeFunction{public:    virtual void operator () (int depth, QWidget *widget) const = 0;};static bool skipWidget(QDesignerFormEditorInterface *core, QWidget *widget){    QDesignerMetaDataBaseItemInterface *item = core->metaDataBase()->item(widget);    if (item == 0)        return true;    QString name = widget->metaObject()->className();    if (name == "QLayoutWidget")        return true;    return false;}static void walkWidgetTree(QDesignerFormEditorInterface *core, int depth, QWidget *widget, const WalkWidgetTreeFunction &func){    if (widget == 0)        return;    if (!widget->isVisible())        return;    if (!skipWidget(core, widget))        func(depth++, widget);    QObjectList child_obj_list = widget->children();    foreach (QObject *child_obj, child_obj_list) {        QWidget *child = qobject_cast<QWidget*>(child_obj);        if (child != 0)            walkWidgetTree(core, depth, child, func);    }}static void grabWidget_helper(QWidget *widget, QPixmap &res, QPixmap &buf,                              const QRect &r, const QPoint &offset, QDesignerFormEditorInterface *core){    buf.fill(widget, r.topLeft());    QPainter::setRedirected(widget, &buf, r.topLeft());    QPaintEvent e(r & widget->rect());    QApplication::sendEvent(widget, &e);    QPainter::restoreRedirected(widget);    {        QPainter pt(&res);        pt.drawPixmap(offset.x(), offset.y(), buf, 0, 0, r.width(), r.height());    }    const QObjectList children = widget->children();    for (int i = 0; i < children.size(); ++i) {        QWidget *child = qobject_cast<QWidget*>(children.at(i));        if (child == 0 || child->isWindow())            continue;        if (child->isHidden() || !child->geometry().intersects(r))            continue;        if (core->metaDataBase()->item(child) != 0)            continue;        QRect cr = r & child->geometry();        cr.translate(-child->pos());        grabWidget_helper(child, res, buf, cr, offset + child->pos(), core);    }}static QPixmap grabWidget(QWidget * widget, QDesignerFormEditorInterface *core){    if (!widget)        return QPixmap();    QRect r = widget->rect();    QSize s = widget->size();    QPixmap res(s), buf(s);    grabWidget_helper(widget, res, buf, r, QPoint(), core);    return res;}/********************************************************************************* QView3D*/class AddTexture : public WalkWidgetTreeFunction{public:    inline AddTexture(QDesignerFormEditorInterface *core, QView3DWidget *w)        : m_core(core), m_3d_widget(w) {}    inline virtual void operator ()(int, QWidget *w) const        { m_3d_widget->addTexture(w, ::grabWidget(w, m_core)); }    QDesignerFormEditorInterface *m_core;    QView3DWidget *m_3d_widget;};class AddWidget : public WalkWidgetTreeFunction{public:    inline AddWidget(QView3DWidget *w) : m_3d_widget(w) {}    inline virtual void operator ()(int depth, QWidget *w) const        { m_3d_widget->addWidget(depth, w); }    QView3DWidget *m_3d_widget;};QView3D::QView3D(QDesignerFormWindowInterface *form_window, QWidget *parent)    : QWidget(parent){    m_form_window = form_window;    m_3d_widget = new QView3DWidget(this);    connect(m_3d_widget, SIGNAL(updateForm()), this, SLOT(updateForm()));    QGridLayout *layout = new QGridLayout(this);    layout->setMargin(0);    layout->addWidget(m_3d_widget, 0, 0, 1, 1);    updateForm();}void QView3D::updateForm(){    QWidget *w = m_form_window->mainContainer();    if (w == 0)        return;    m_3d_widget->clear();    walkWidgetTree(m_form_window->core(), 0, w, AddTexture(m_form_window->core(), m_3d_widget));    m_3d_widget->beginAddingWidgets(w);    walkWidgetTree(m_form_window->core(), 0, w, AddWidget(m_3d_widget));    m_3d_widget->endAddingWidgets();}#include "view3d.moc"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -