OpenGL QT 4代码在QT5中不显示QLogo(helloworld示例)

OpenGL QT 4代码在QT5中不显示QLogo(helloworld示例),qt,opengl,mingw,version,Qt,Opengl,Mingw,Version,应用程序编译和运行时不会出现编译器错误,但不会显示Q徽标。 我以QT徽标OpenGL为例 并尝试在QT版本5.2.1(MSVC 2010,32位)中编译。我知道在版本5中使用OpenGL的方式与旧版本4有所不同。我已经修改了一个正在工作的GL示例中的一些代码,但仍然不起作用。我打赌QtLogo中存在问题,因为我没有更改这些文件中的任何内容。因此,作为OpenGL的新手,我完全感到困惑。 我希望已经提供了一个下降问题声明。回答这个问题将有助于其他许多人解开QT OpenGL变化的奥秘。这太令人沮丧

应用程序编译和运行时不会出现编译器错误,但不会显示Q徽标。 我以QT徽标OpenGL为例 并尝试在QT版本5.2.1(MSVC 2010,32位)中编译。我知道在版本5中使用OpenGL的方式与旧版本4有所不同。我已经修改了一个正在工作的GL示例中的一些代码,但仍然不起作用。我打赌QtLogo中存在问题,因为我没有更改这些文件中的任何内容。因此,作为OpenGL的新手,我完全感到困惑。 我希望已经提供了一个下降问题声明。回答这个问题将有助于其他许多人解开QT OpenGL变化的奥秘。这太令人沮丧了

1) QT版本5.2.1(MSVC 2010,32位)-与QT 5.2.1 for Windows 32位(MinGW 4.8,OpenGL,634 MB)安装程序一起安装 2) Windows 7,尝试了32位和64位 3) 英特尔CPU(使用两台不同的基于英特尔的计算机) 4) 该应用程序在QT版本4中工作正常

5) 代码可供下载

代码如下:

你好

# HELLOGL


#VPATH += ../shared
#INCLUDEPATH += ../shared

QT += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = hellogl
TEMPLATE = app


SOURCES       += main.cpp \
                 window.cpp \
                 glwidget.cpp \
                 qtlogo.cpp

HEADERS       += window.h \
                glwidget.h \
                qtlogo.h

FORMS         += window.ui 
GLWIDGET.H

// glwidget.h


#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QGLWidget>

class QtLogo;

class GLWidget : public QGLWidget
{
    Q_OBJECT

public:
    explicit GLWidget(QWidget *parent = 0);
    ~GLWidget();

    QSize minimumSizeHint() const;
    QSize sizeHint() const;

public slots:
    void setXRotation(int angle);
    void setYRotation(int angle);
    void setZRotation(int angle);

signals:
    void xRotationChanged(int angle);
    void yRotationChanged(int angle);
    void zRotationChanged(int angle);

protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int width, int height);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);

private:
    QtLogo *logo;
    int xRot;
    int yRot;
    int zRot;
    QPoint lastPos;
    QColor qtGreen;
    QColor qtPurple;
};

#endif
//glwidget.h
#ifndef GLU H
#定义glu\H
#包括
类别标志;
类GLWidget:publicqglwidget
{
Q_对象
公众:
显式GLWidget(QWidget*parent=0);
~GLWidget();
QSize minimumSizeHint()常量;
QSize sizeHint()常量;
公众时段:
无效设置x旋转(内角);
空隙沉降(内角);
空隙设置旋转(内角);
信号:
空隙X旋转变化(内倾角);
无效旋转变化(内角);
无效zRotationChanged(内角);
受保护的:
void initializeGL();
void paintGL();
空隙大小(内部宽度、内部高度);
作废鼠标压力事件(QMouseEvent*事件);
作废mouseMoveEvent(QMouseEvent*事件);
私人:
QtLogo*标识;
int-xRot;
int yRot;
int-zRot;
QPoint-lastPos;
QColor绿色;
QColor紫色;
};
#恩迪夫
qtlogo.h

//qtlogo.h


#ifndef QTLOGO_H
#define QTLOGO_H

//#include <QObject>
//#include <QtOpenGL>
#include <QColor>
#include <GL/gl.h>

//#include <QGLWidget>
//#include <QtWidgets>

#include <QMatrix4x4>
#include <QVector3D>

#include <qmath.h>


class Patch;
class Geometry;

//! [0]
class QtLogo : public QObject
{
public:
    QtLogo(QObject *parent, int d = 64, qreal s = 1.0);
    ~QtLogo();
    void setColor(QColor c);
    void draw() const;
private:
    void buildGeometry(int d, qreal s);

    QList<Patch *> parts;
    Geometry *geom;
};
//! [0]

#endif // QTLOGO_H
//qtlogo.h
#ifndef QTU H
#定义qtuh
//#包括
//#包括
#包括
#包括
//#包括
//#包括
#包括
#包括
#包括
类补丁;
类几何;
//! [0]
类别QtLogo:公共QObject
{
公众:
QtLogo(QObject*父对象,int d=64,qreal s=1.0);
~QtLogo();
void setColor(QColor c);
void draw()常量;
私人:
虚空建筑几何(int d,qreal s);
QList部件;
几何*geom;
};
//! [0]
#endif//qtu\H
窗户

// window.h


#ifndef WINDOW_H
#define WINDOW_H


//#include <QObject>

//#include <QApplication>
//#include <QHBoxLayout>

//#include <QSpinBox>
//#include <QKeyEvent>

#include <QWidget>
#include <QSlider>

class QSlider;

class GLWidget;

namespace Ui {
class Window;
}

class Window : public QWidget
{
    Q_OBJECT

public:
    explicit Window(QWidget *parent = 0);
    ~Window();

protected:
    void keyPressEvent(QKeyEvent *event);

private:
    Ui::Window *ui;
    QSlider *createSlider();

    GLWidget *glWidget;
    QSlider *xSlider;
    QSlider *ySlider;
    QSlider *zSlider;


};

#endif
//window.h
#ifndef窗口
#定义窗口
//#包括
//#包括
//#包括
//#包括
//#包括
#包括
#包括
类QSlider;
类GLWidget;
名称空间用户界面{
类窗口;
}
类窗口:公共QWidget
{
Q_对象
公众:
显式窗口(QWidget*parent=0);
~Window();
受保护的:
无效按键事件(QKeyEvent*事件);
私人:
Ui::Window*Ui;
QSlider*createSlider();
GLWidget*GLWidget;
QSlider*xSlider;
QSlider*ySlider;
QSlider*zSlider;
};
#恩迪夫
glwidget.cpp

// glwidget.cpp


#include <math.h>

#include <QtWidgets>
#include <QtOpenGL>
#include "glwidget.h"
#include "qtlogo.h"

//#include <QColor>

/*
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE  0x809D
#endif
*/


GLWidget::GLWidget(QWidget *parent)
    : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
    logo = 0;
    xRot = 0;
    yRot = 0;
    zRot = 0;

    qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
    qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
}

GLWidget::~GLWidget()
{
}

QSize GLWidget::minimumSizeHint() const
{
    return QSize(50, 50); //
}

QSize GLWidget::sizeHint() const
{
    return QSize(800, 800);
}

static void qNormalizeAngle(int &angle)
{
    while (angle < 0)
        angle += 360 * 16;
    while (angle > 360 * 16)
        angle -= 360 * 16;
}

void GLWidget::setXRotation(int angle)
{
    qNormalizeAngle(angle);
    if (angle != xRot) {
        xRot = angle;
        emit xRotationChanged(angle);
        updateGL();
    }
}

void GLWidget::setYRotation(int angle)
{
    qNormalizeAngle(angle);
    if (angle != yRot) {
        yRot = angle;
        emit yRotationChanged(angle);
        updateGL();
    }
}

void GLWidget::setZRotation(int angle)
{
    qNormalizeAngle(angle);
    if (angle != zRot) {
        zRot = angle;

        emit zRotationChanged(angle);
        updateGL();
    }
}

void GLWidget::initializeGL()
{
    qglClearColor(qtPurple.dark());

    logo = new QtLogo(this, 64);
    logo->setColor(qtGreen.dark());

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_MULTISAMPLE);
    static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
}

void GLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -10.0);
    glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
    glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
    glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);
    logo->draw();
    //logo->setColor(QColor(0,0,0));
}

void GLWidget::resizeGL(int width, int height)
{
    int side = qMin(width, height);
    glViewport((width - side) / 2, (height - side) / 2, side, side);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
#ifdef QT_OPENGL_ES_1
    glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
#else
    glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0);
#endif
    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::mousePressEvent(QMouseEvent *event)
{
    lastPos = event->pos();
}

void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
    int dx = event->x() - lastPos.x();
    int dy = event->y() - lastPos.y();

    if (event->buttons() & Qt::LeftButton) {
        setXRotation(xRot + 8 * dy);
        setYRotation(yRot + 8 * dx);
    } else if (event->buttons() & Qt::RightButton) {
        setXRotation(xRot + 8 * dy);
        setZRotation(zRot + 8 * dx);
    }
    lastPos = event->pos();
}
//glwidget.cpp
#包括
#包括
#包括
#包括“glwidget.h”
#包括“qtlogo.h”
//#包括
/*
#ifndef GL_多样本
#定义GL_多样本0x809D
#恩迪夫
*/
GLWidget::GLWidget(QWidget*父项)
:QGLWidget(QGLFormat(QGL::SampleBuffers),父级)
{
logo=0;
xRot=0;
yRot=0;
zRot=0;
qtGreen=QColor::fromCmykF(0.40,0.0,1.0,0.0);
qtpulper=QColor::fromCmykF(0.39,0.39,0.0,0.0);
}
GLWidget::~GLWidget()
{
}
QSize GLWidget::minimumSizeHint()常量
{
返回QSize(50,50)//
}
QSize GLWidget::sizeHint()常量
{
返回QSize(800800);
}
静态无效qNormalizeAngle(内角和角度)
{
而(角度<0)
角度+=360*16;
同时(角度>360*16)
角度-=360*16;
}
void GLWidget::setXRotation(整数角度)
{
角;
如果(角度!=xRot){
xRot=角度;
发射X旋转改变(角度);
updateGL();
}
}
void GLWidget::setyrotion(内角)
{
角;
如果(角度!=yRot){
yRot=角度;
发射旋转改变(角度);
updateGL();
}
}
void GLWidget::setZRotation(内角)
{
角;
如果(角度!=zRot){
zRot=角度;
发射zRotationChanged(角度);
updateGL();
}
}
void GLWidget::initializeGL()
{
qglClearColor(qtpulper.dark());
logo=新的QtLogo(本,64);
logo->setColor(qtGreen.dark());
glEnable(GLU深度试验);
glEnable(GL_CULL_面);
glShadeModel(GL_平滑);
glEnable(德国劳埃德大学照明);
glEnable(GL_LIGHT0);
glEnable(GL_多样本);
静态GLfloat lightPosition[4]={0.5,5.0,7.0,1.0};
glLightfv(GL_LIGHT0,GL_位置,lightPosition);
}
void GLWidget::paintGL()
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glLoadIdentity();
glTranslatef(0.0,0.0,-10.0);
glRotatef(xRot/16.0,1.0,0.0,0.0);
glRotatef(yRot/16.0,0.0,1.0,0.0);
glRotatef(zRot/16.0,0.0,0.0,1.0);
logo->draw();
//logo->setColor(QColor(0,0,0));
}
void GLWidget::resizeGL(整数宽度、整数高度)
{
内侧=qMin(宽度、高度);
glViewport((宽度-侧面)/2,(高度-侧面)/2,侧面,侧面);
glMatrixMode(GL_投影);
glLoadIdentity();
#ifdef QT_OPENGL_ES_1
格洛托夫-0.5,0.5,0.5,0.5,4.0,15.0);
#否则
格洛托-0.5,0.5,0.5,0.5,4.0,15.0);
#恩迪夫
glMatrixMode(GLU模型视图);
}
void GLWidget::MousePresseEvent(QMouseEvent*事件)
{
lastPos=事件->位置();
}
void GLWidget::mouseMoveEvent(QMouseEvent*事件)
{
int dx=event->x()-lastPos.x();
int dy=event->y()-lastPos.y();
if(事件->按钮()&Qt::LeftButton){
设置X旋转(X旋转+8*dy);
设定值(yRot+8*dx);
}else if(事件->按钮()&Qt::RightButton){
设置X旋转(X旋转+8*dy);
设置Zrotation(zRot+8*dx);
}
lastPos=事件->位置();
}
main.cpp

// main.cpp


#include <QtOpenGL>
#include <QtGui>

#include <QApplication>

#include <QDesktopWidget>

#include "window.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Window window;
    window.resize(window.sizeHint());
    int desktopArea = QApplication::desktop()->width() *
                     QApplication::desktop()->height();
    int widgetArea = window.width() * window.height();
    if (((float)widgetArea / (float)desktopArea) < 0.75f)
        window.show();
    else
        window.showMaximized();
    return app.exec();
}
//main.cpp
#包括
#包括
// qtlogo.cpp


#include "qtlogo.h"


static const qreal tee_height = 0.311126;
static const qreal cross_width = 0.25;
static const qreal bar_thickness = 0.113137;
static const qreal inside_diam = 0.20;
static const qreal outside_diam = 0.30;
static const qreal logo_depth = 0.10;
static const int num_divisions = 32;

//! [0]
struct Geometry
{
    QVector<GLushort> faces;
    QVector<QVector3D> vertices;
    QVector<QVector3D> normals;
    void appendSmooth(const QVector3D &a, const QVector3D &n, int from);
    void appendFaceted(const QVector3D &a, const QVector3D &n);
    void finalize();
    void loadArrays() const;
};
//! [0]

//! [1]
class Patch
{
public:
    enum Smoothing { Faceted, Smooth };
    Patch(Geometry *);
    void setSmoothing(Smoothing s) { sm = s; }
    void translate(const QVector3D &t);
    void rotate(qreal deg, QVector3D axis);
    void draw() const;
    void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n);
    void addQuad(const QVector3D &a, const QVector3D &b,  const QVector3D &c, const QVector3D &d);

    GLushort start;
    GLushort count;
    GLushort initv;

    GLfloat faceColor[4];
    QMatrix4x4 mat;
    Smoothing sm;
    Geometry *geom;
};
//! [1]

static inline void qSetColor(float colorVec[], QColor c)
{
    colorVec[0] = c.redF();
    colorVec[1] = c.greenF();
    colorVec[2] = c.blueF();
    colorVec[3] = c.alphaF();
}

void Geometry::loadArrays() const
{
    glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
    glNormalPointer(GL_FLOAT, 0, normals.constData());
}

void Geometry::finalize()
{
    // TODO: add vertex buffer uploading here

    // Finish smoothing normals by ensuring accumulated normals are returned
    // to length 1.0.
    for (int i = 0; i < normals.count(); ++i)
        normals[i].normalize();
}

void Geometry::appendSmooth(const QVector3D &a, const QVector3D &n, int from)
{
    // Smooth normals are acheived by averaging the normals for faces meeting
    // at a point.  First find the point in geometry already generated
    // (working backwards, since most often the points shared are between faces
    // recently added).
    int v = vertices.count() - 1;
    for ( ; v >= from; --v)
        if (qFuzzyCompare(vertices[v], a))
            break;
    if (v < from)
    {
        // The vert was not found so add it as a new one, and initialize
        // its corresponding normal
        v = vertices.count();
        vertices.append(a);
        normals.append(n);
    }
    else
    {
        // Vert found, accumulate normals into corresponding normal slot.
        // Must call finalize once finished accumulating normals
        normals[v] += n;
    }
    // In both cases (found or not) reference the vert via its index
    faces.append(v);
}

void Geometry::appendFaceted(const QVector3D &a, const QVector3D &n)
{
    // Faceted normals are achieved by duplicating the vert for every
    // normal, so that faces meeting at a vert get a sharp edge.
    int v = vertices.count();
    vertices.append(a);
    normals.append(n);
    faces.append(v);
}

Patch::Patch(Geometry *g)
   : start(g->faces.count())
   , count(0)
   , initv(g->vertices.count())
   , sm(Patch::Smooth)
   , geom(g)
{
    qSetColor(faceColor, QColor(Qt::darkGray));
}

void Patch::rotate(qreal deg, QVector3D axis)
{
    mat.rotate(deg, axis);
}

void Patch::translate(const QVector3D &t)
{
    mat.translate(t);
}

static inline void qMultMatrix(const QMatrix4x4 &mat)
{
    if (sizeof(qreal) == sizeof(GLfloat))
        glMultMatrixf((GLfloat*)mat.constData());
#ifndef QT_OPENGL_ES
    else if (sizeof(qreal) == sizeof(GLdouble))
        glMultMatrixd((GLdouble*)mat.constData());
#endif
    else
    {
        GLfloat fmat[16];
        GLfloat const *r = mat.constData();
        for (int i = 0; i < 16; ++i)
            fmat[i] = r[i];
        glMultMatrixf(fmat);
    }
}

//! [2]
void Patch::draw() const
{
    glPushMatrix();
    qMultMatrix(mat);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor);

    const GLushort *indices = geom->faces.constData();
    glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start);
    glPopMatrix();
}
//! [2]

void Patch::addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n)
{
    QVector3D norm = n.isNull() ? QVector3D::normal(a, b, c) : n;
    if (sm == Smooth)
    {
        geom->appendSmooth(a, norm, initv);
        geom->appendSmooth(b, norm, initv);
        geom->appendSmooth(c, norm, initv);
    }
    else
    {
        geom->appendFaceted(a, norm);
        geom->appendFaceted(b, norm);
        geom->appendFaceted(c, norm);
    }
    count += 3;
}

void Patch::addQuad(const QVector3D &a, const QVector3D &b,  const QVector3D &c, const QVector3D &d)
{
    QVector3D norm = QVector3D::normal(a, b, c);
    if (sm == Smooth)
    {
        addTri(a, b, c, norm);
        addTri(a, c, d, norm);
    }
    else
    {
        // If faceted share the two common verts
        addTri(a, b, c, norm);
        int k = geom->vertices.count();
        geom->appendSmooth(a, norm, k);
        geom->appendSmooth(c, norm, k);
        geom->appendFaceted(d, norm);
        count += 3;
    }
}

static inline QVector<QVector3D> extrude(const QVector<QVector3D> &verts, qreal depth)
{
    QVector<QVector3D> extr = verts;
    for (int v = 0; v < extr.count(); ++v)
        extr[v].setZ(extr[v].z() - depth);
    return extr;
}

class Rectoid
{
public:
    void translate(const QVector3D &t)
    {
        for (int i = 0; i < parts.count(); ++i)
            parts[i]->translate(t);
    }
    void rotate(qreal deg, QVector3D axis)
    {
        for (int i = 0; i < parts.count(); ++i)
            parts[i]->rotate(deg, axis);
    }

    // No special Rectoid destructor - the parts are fetched out of this member
    // variable, and destroyed by the new owner
    QList<Patch*> parts;
};

class RectPrism : public Rectoid
{
public:
    RectPrism(Geometry *g, qreal width, qreal height, qreal depth);
};

RectPrism::RectPrism(Geometry *g, qreal width, qreal height, qreal depth)
{
    enum { bl, br, tr, tl };
    Patch *fb = new Patch(g);
    fb->setSmoothing(Patch::Faceted);

    // front face
    QVector<QVector3D> r(4);
    r[br].setX(width);
    r[tr].setX(width);
    r[tr].setY(height);
    r[tl].setY(height);
    QVector3D adjToCenter(-width / 2.0, -height / 2.0, depth / 2.0);
    for (int i = 0; i < 4; ++i)
        r[i] += adjToCenter;
    fb->addQuad(r[bl], r[br], r[tr], r[tl]);

    // back face
    QVector<QVector3D> s = extrude(r, depth);
    fb->addQuad(s[tl], s[tr], s[br], s[bl]);

    // side faces
    Patch *sides = new Patch(g);
    sides->setSmoothing(Patch::Faceted);
    sides->addQuad(s[bl], s[br], r[br], r[bl]);
    sides->addQuad(s[br], s[tr], r[tr], r[br]);
    sides->addQuad(s[tr], s[tl], r[tl], r[tr]);
    sides->addQuad(s[tl], s[bl], r[bl], r[tl]);

    parts << fb << sides;
}

class RectTorus : public Rectoid
{
public:
    RectTorus(Geometry *g, qreal iRad, qreal oRad, qreal depth, int numSectors);
};

RectTorus::RectTorus(Geometry *g, qreal iRad, qreal oRad, qreal depth, int k)
{
    QVector<QVector3D> inside;
    QVector<QVector3D> outside;
    for (int i = 0; i < k; ++i) {
        qreal angle = (i * 2 * M_PI) / k;
        inside << QVector3D(iRad * qSin(angle), iRad * qCos(angle), depth / 2.0);
        outside << QVector3D(oRad * qSin(angle), oRad * qCos(angle), depth / 2.0);
    }
    inside << QVector3D(0.0, iRad, 0.0);
    outside << QVector3D(0.0, oRad, 0.0);
    QVector<QVector3D> in_back = extrude(inside, depth);
    QVector<QVector3D> out_back = extrude(outside, depth);

    // Create front, back and sides as separate patches so that smooth normals
    // are generated for the curving sides, but a faceted edge is created between
    // sides and front/back
    Patch *front = new Patch(g);
    for (int i = 0; i < k; ++i)
        front->addQuad(outside[i], inside[i],
                       inside[(i + 1) % k], outside[(i + 1) % k]);
    Patch *back = new Patch(g);
    for (int i = 0; i < k; ++i)
        back->addQuad(in_back[i], out_back[i],
                      out_back[(i + 1) % k], in_back[(i + 1) % k]);
    Patch *is = new Patch(g);
    for (int i = 0; i < k; ++i)
        is->addQuad(in_back[i], in_back[(i + 1) % k],
                    inside[(i + 1) % k], inside[i]);
    Patch *os = new Patch(g);
    for (int i = 0; i < k; ++i)
        os->addQuad(out_back[(i + 1) % k], out_back[i],
                    outside[i], outside[(i + 1) % k]);
    parts << front << back << is << os;
}

QtLogo::QtLogo(QObject *parent, int divisions, qreal scale)
    : QObject(parent)
    , geom(new Geometry())
{
    buildGeometry(divisions, scale);
}

QtLogo::~QtLogo()
{
    qDeleteAll(parts);
    delete geom;
}

void QtLogo::setColor(QColor c)
{
    for (int i = 0; i < parts.count(); ++i)
        qSetColor(parts[i]->faceColor, c);
}

//! [3]
void QtLogo::buildGeometry(int divisions, qreal scale)
{
    qreal cw = cross_width * scale;
    qreal bt = bar_thickness * scale;
    qreal ld = logo_depth * scale;
    qreal th = tee_height *scale;

    RectPrism cross(geom, cw, bt, ld);
    RectPrism stem(geom, bt, th, ld);

    QVector3D z(0.0, 0.0, 1.0);
    cross.rotate(45.0, z);
    stem.rotate(45.0, z);

    qreal stem_downshift = (th + bt) / 2.0;
    stem.translate(QVector3D(0.0, -stem_downshift, 0.0));

    RectTorus body(geom, 0.20, 0.30, 0.1, divisions);

    parts << stem.parts << cross.parts << body.parts;

    geom->finalize();
}
//! [3]

//! [4]
void QtLogo::draw() const
{
    geom->loadArrays();

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    for (int i = 0; i < parts.count(); ++i)
        parts[i]->draw();

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
}
//! [4]
// window.cpp


#include <QtWidgets>
#include "window.h"
#include "ui_window.h"
#include "glwidget.h"
#include <QSlider>

Window::Window(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Window)
{
    ui->setupUi(this);

    //glWidget = new GLWidget;
    glWidget = ui->widget;

    xSlider = createSlider();
    ySlider = createSlider();
    zSlider = createSlider();

    connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int)));
    connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int)));
    connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int)));
    connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int)));
    connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int)));
    connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int)));

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addWidget(glWidget);
    mainLayout->addWidget(xSlider);
    mainLayout->addWidget(ySlider);
    mainLayout->addWidget(zSlider);
    setLayout(mainLayout);

    xSlider->setValue(15 * 16);
    ySlider->setValue(345 * 16);
    zSlider->setValue(0 * 16);
    setWindowTitle(tr("Hello GL"));
}

QSlider *Window::createSlider()
{
    QSlider *slider = new QSlider(Qt::Vertical);
    slider->setRange(0, 360 * 16);
    slider->setSingleStep(16);
    slider->setPageStep(15 * 16);
    slider->setTickInterval(15 * 16);
    slider->setTickPosition(QSlider::TicksRight);
    return slider;
}

Window::~Window()
{
    delete ui;
}

void Window::keyPressEvent(QKeyEvent *e)
{
    if (e->key() == Qt::Key_Escape)
        close();
    else
        QWidget::keyPressEvent(e);
}
    /*
#ifndef QT_OPENGL_ES
    else if (sizeof(qreal) == sizeof(GLdouble))
    glMultMatrixd((GLdouble*)mat.constData());
#endif
*/