逛奔的蜗牛

我不聪明,但我会很努力

   ::  :: 新随笔 ::  ::  :: 管理 ::

==================================[GLWidget.h]==================================

#ifndef GLWIDGET_H

#define GLWIDGET_H


#include <QtOpenGL/QGLWidget>


class GLWidget : public QGLWidget {

    Q_OBJECT


public:

    GLWidget(QWidget *parent = 0);

    ~GLWidget();


protected:

    virtual void initializeGL();

    virtual void resizeGL(int w, int h);

    virtual void paintGL();


    virtual void hideEvent(QHideEvent *event);

    virtual void showEvent(QShowEvent *event);

    virtual void timerEvent(QTimerEvent *event);

    virtual void mousePressEvent(QMouseEvent *event);

    virtual void mouseMoveEvent(QMouseEvent *event);

    virtual void mouseReleaseEvent(QMouseEvent *event);

    virtual void wheelEvent(QWheelEvent *event);


private:

    int     timerId;

    QPoint  lastPos;

    GLfloat rotateX;

    GLfloat rotateY;

    GLfloat rotateZ;

    GLfloat zoom;


    void drawCube(GLfloat factorX = 1, GLfloat factorY = 1,

                  GLfloat factorZ = 1, GLfloat w = 1);

    void drawCone(GLfloat radius = 1.0f, GLfloat height = 1,

                  GLuint steps = 18);

};


#endif // GLWIDGET_H



==================================[GLWidget.cpp]==================================

#include "GLWidget.h"

#include <qDebug>

#include <QTimerEvent>

#include <QMouseEvent>

#include <cmath>


GLWidget::GLWidget(QWidget *parent)

    : QGLWidget(parent) {

    setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));


    rotateX = 0.0f;

    rotateY = 0.0f;

    rotateZ = 0.0f;

    zoom = 1.0f;

}


GLWidget::~GLWidget() {


}


void GLWidget::hideEvent(QHideEvent *event) {

    this->killTimer(this->timerId);

}


void GLWidget::showEvent(QShowEvent *event) {

    this->timerId = this->startTimer(500);

}


void GLWidget::timerEvent(QTimerEvent *event) {

    if (event->timerId() == this->timerId) {

    } else {

        QGLWidget::timerEvent(event);

    }

}


void GLWidget::mousePressEvent(QMouseEvent *event) {

    if (Qt::LeftButton == event->button()) {

        lastPos = event->pos();

    } else if (Qt::RightButton == event->button()) {

        lastPos = event->pos();

    }

}


void GLWidget::mouseMoveEvent(QMouseEvent *event) {

    if (Qt::LeftButton & event->buttons()) {

        GLfloat dx = event->pos().x() - lastPos.x();

        GLfloat dy = event->pos().y() - lastPos.y();


        rotateX += dy;

        rotateY += dx;


        updateGL();

        //qDebug() << QString("RotateX:%1, RotateY:%2").arg(rotateX).arg(rotateY);

    } else if (Qt::RightButton & event->buttons()) {

        GLfloat dz = event->pos().y() - lastPos.y();

        dz *= 0.01f;

        zoom += dz;

        updateGL();

    }


    lastPos = event->pos();

}


void GLWidget::mouseReleaseEvent(QMouseEvent *event) {


}


void GLWidget::wheelEvent(QWheelEvent *event) {

    GLfloat degrees = event->delta();

    zoom -= degrees * 0.0002f;

    // 注意, 如果zoom为负值, eye就会被放置到z轴的负方向, 而从物体的背面看了.

    if (zoom < 1.0f) {

        zoom = 1.0f;

    }


    updateGL();

}


///////////////////////////////////////////////////////////////////////////////

//                               Opengl Code

///////////////////////////////////////////////////////////////////////////////

void GLWidget::initializeGL() {

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    glEnable(GL_DEPTH_TEST);

    glFrontFace(GL_CCW);

    //glEnable(GL_CULL_FACE);

    glCullFace(GL_BACK);

    glShadeModel(GL_SMOOTH);


    // Point size

    // glPointSize(GLfloat size);

    GLfloat sizes[2];

    GLfloat step;

    glGetFloatv(GL_LINE_WIDTH_RANGE, sizes);

    glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &step);

}


void GLWidget::resizeGL(int w, int h) {

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    gluPerspective(75, (GLdouble)w / h, 0.1, 100);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}


void GLWidget::paintGL() {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    //glTranslatef(0.0f, 0.0f, zoom);

    gluLookAt(0.0f, 0.0f, zoom, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);


    glRotatef(rotateX, 1, 0, 0);

    glRotatef(rotateY, 0, 1, 0);

    glRotatef(rotateZ, 0, 0, 1);


    // Real draw code.

    //glColor3f(1.0f, 0.0f, 0.0f);

    //drawCube(1, 1, 1, 1);

    glPolygonMode(GL_BACK, GL_LINE);

    drawCone(1.0f, 1.50, 48);


}


void GLWidget::drawCube(GLfloat factorX, GLfloat factorY,

                        GLfloat factorZ, GLfloat w) {

    GLfloat x = factorX * 0.5f;

    GLfloat y = factorY * 0.5f;

    GLfloat z = factorZ * 0.5f;


    // x / w, y / w, z / w

    // 前左下, 前右下, 前右上, 前左上: p0, p1, p2, p3

    // 后左下, 后右下, 后右上, 后左上: p4, p5, p6, p7

    GLfloat p0[4] = {-x, -y, z, w};

    GLfloat p1[4] = {x, -y, z, w};

    GLfloat p2[4] = {x, y, z, w};

    GLfloat p3[4] = {-x, y, z, w};


    GLfloat p4[4] = {-x, -y, -z, w};

    GLfloat p5[4] = {x, -y, -z, w};

    GLfloat p6[4] = {x, y, -z, w};

    GLfloat p7[4] = {-x, y, -z, w};


    // 开始绘制Cube的六个面: 逆时针

    glBegin(GL_QUADS);

    // 前面: p0, p1, p2, p3

    glVertex4fv(p0);

    glVertex4fv(p1);

    glVertex4fv(p2);

    glVertex4fv(p3);

    // 右面: p1, p5, p6, p2

    glVertex4fv(p1);

    glVertex4fv(p5);

    glVertex4fv(p6);

    glVertex4fv(p2);

    // 后面: p5, p4, p7, p6

    glVertex4fv(p5);

    glVertex4fv(p4);

    glVertex4fv(p7);

    glVertex4fv(p6);

    // 左右: p4, p0, p3, p7

    glVertex4fv(p4);

    glVertex4fv(p0);

    glVertex4fv(p3);

    glVertex4fv(p7);

    // 上面: p2, p6, p7, p3

    glVertex4fv(p2);

    glVertex4fv(p6);

    glVertex4fv(p7);

    glVertex4fv(p3);

    // 下面: p0, p4, p5, p1

    glVertex4fv(p0);

    glVertex4fv(p4);

    glVertex4fv(p5);

    glVertex4fv(p1);

    glEnd();

}



void GLWidget::drawCone(GLfloat radius, GLfloat height,

                        GLuint steps) {

    const GLfloat GL_PI = 3.1415f;

    GLfloat angles = 2 * GL_PI / steps;

    GLfloat vertices[steps][3];


    for (int i = 0; i < steps; ++i) {

        vertices[i][0] = radius * cos(i * angles);

        vertices[i][1] = radius * sin(i * angles);

        vertices[i][2] = 0;

    }


    // top surface

    glBegin(GL_TRIANGLE_FAN);

        glColor3f(0.0f, 0.0f, 1.0f);

        glVertex3f(0.0f, 0.0f, height);

        for (int i = 0; i < steps; ++i) {

            glVertex3fv(vertices[i]);

            if ((i & 1) == 0) {

                glColor3f(1.0f, 0.0f, 0.0f);

            } else {

                glColor3f(0.0f, 0.0f, 1.0f);

            }

        }

        glVertex3fv(vertices[0]);

    glEnd();


    // bottom surface

    glBegin(GL_TRIANGLE_FAN);

        glVertex3f(0.0f, 0.0f, 0);

        for (int i = steps - 1; i >= 0; --i) {

            glVertex3fv(vertices[i]);

            if ((i & 1) == 0) {

                glColor3f(0.0f, 1.0f, 0.0f);

            } else {

                glColor3f(1.0f, 0.0f, 1.0f);

            }

        }

        glVertex3fv(vertices[steps - 1]);

    glEnd();

}


posted on 2009-05-19 15:15 逛奔的蜗牛 阅读(2933) 评论(1)  编辑 收藏 引用 所属分类: QtOpenGL

评论

# re: Qt: OpenGL模板 2012-12-14 15:19 wsc
GLfloat vertices[steps][3];这句代码有错误。不能这样用变量定义数组吧。应该用循环吧?  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理