《QT Creator快速入门》第十二章:3D绘图

摘要:
OpenGL是一套跨平台的用来渲染3D图形的API。以及状态使用函数,这类函数会根据当前OpenGL的状态执行一些操作。而如果将z_translate设为正值的话相当于是在眼睛的后方,这样更不能看见了:voidglMatrixMode:将当前矩阵设置成参数所指定的模式,以满足不同绘图所需执行的矩阵变换。

OpenGL是一套跨平台的用来渲染3D图形的API。OpenGL自身是一个巨大的状态机:一系列的变量描述OpenGL此刻应当如何运行,OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲,最后,我们使用当前OpenGL上下文来渲染。

假设当我们想告诉OpenGL去画线段而不是三角形的时候,我们通过改变一些上下文变量来改变OpenGL状态,从而告诉OpenGL如何去绘图。一旦我们改变了OpenGL的状态为绘制线段,下一个绘制命令就会画出线段而不是三角形。

当使用OpenGL的时候,我们会遇到一些状态设置函数,这类函数将会改变上下文。以及状态使用函数,这类函数会根据当前OpenGL的状态执行一些操作。比如下面例子中的glClearColor()函数是一个状态设置函数,而glClear()函数则是一个状态使用的函数,它使用了当前的状态来获取应该清除为的颜色。

Qt中的QtOpenGL模块提供了使用OpenGL的方法,使用它需要在.pro项目文件中添加QT+=opengl。QGLWidget是QtOpenGL模块中的一个类,它是一个用来渲染OpenGL图形的部件,可以继承该类后来像使用其它QWidget部件一样使用它。QGLWidget提供了3个虚函数重写它们来实现指定操作:

initializeGL():设置OpenGL渲染环境,定义显示列表等,只在resizeGL()、paintGL()之前被调用一次。

resizeGL():设置OpenGL的视口,投影等,部件大小改变的时候被调用。

paintGL():渲染OpenGL场景,当部件需要更新时被调用。

Qt中有一个Hello GL示例程序,它在OpenGL分类中。

1、基本绘制

下面代码使用QGLWidget绘制了一个直线、三角形、文本,其中的MyGLWidget继承自QGLWidget:

#include <QApplication>#include "myglwidget.h"

int main(int argc, char**argv)
{
    QApplication app(argc, argv);

    MyGLWidget w;
    w.resize(600, 400);
    w.show();

    returnapp.exec();
}
View Code
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H#include <QGLWidget>#include <GL/glu.h>

class MyGLWidget: publicQGLWidget
{
    voidinitializeGL()
    {
        //void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);
        glClearColor(1.0, 0.0, 0.0, 0.0); //设置清除屏幕(glClear()方法)时使用的颜色为红色
glShadeModel(GL_SMOOTH); //设置阴影平滑
    
        //void glClearDepth(GLclampd depth);
        glClearDepth(1.0); //设置深度缓存(深度缓冲区中每个像素需要的值)
glEnable(GL_DEPTH_TEST); //启用深度测试功能,根据坐标的远近自动隐藏被遮住的图形(材料)
}
    void resizeGL(int w, inth)
    {
        //设置视口的大小:告诉OpenGL渲染窗口的尺寸大小
        //也可以将视口的维度设置为比窗口的维度小,这样OpenGL渲染将会在一个小窗口中显示,这样子我们也可以将一些其它元素显示在OpenGL视口之外
        glViewport(0, 0, (GLint)w, (GLint)h);
    
        glMatrixMode(GL_PROJECTION); //投影矩阵模式
        glLoadIdentity(); //重置当前指定的矩阵为单位矩阵,这样可以将矩阵恢复到初始状态。
        gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //设置透视投影矩阵:视角为45度,纵横比为窗口的纵横比,最近和最远的位置分别为0.1和100
glMatrixMode(GL_MODELVIEW); //设置模型视图矩阵
        glLoadIdentity(); //重置模型视图矩阵
}
    voidpaintGL()
    {
        //在每个新的渲染迭代开始的时候我们总是希望清屏,否则我们仍能看见上一次迭代的渲染结果
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕:使用glClearColor()设置的颜色和glClearDepth()设置的深度缓存
        glLoadIdentity(); //重置模型视图矩阵,这样便将坐标原点移到了窗口中心
GLfloat z_translate = -6.0;
        //void glTranslatef(GLfloat x,GLfloat y,GLfloat z);
        //移动坐标原点,是相对于当前点来移动的,对于z来说正数为向屏幕外移动(相当于在眼睛后方,所以就看不到了),负数为向屏幕内移动(绝对值越大离眼睛越远,看起来越小)
        glTranslatef(0.0, 0.0, z_translate); //将坐标原点内移6.0
glBegin(GL_LINES); //开始绘制直线
        glVertex3f(0.0, 1.0, 0.0);
        glVertex3f(1.0, 1.0, 0.0);
        glEnd();
    
        glBegin(GL_TRIANGLES); //开始绘制三角形
        //逆时针绘制各顶点
        //void glVertex3f(GLfloat x,GLfloat y,GLfloat z);
        glVertex3f(0.0, 1.0, 0.0);
        glVertex3f(-1.0, -1.0, 0.0);
        glVertex3f(1.0, -1.0, 0.0);
        glEnd();
    
        //void renderText(double x, double y, double z, const QString & str,
        //const QFont & fnt = QFont(), int listBase = 2000);
        renderText(0.0, 2.0, 0.0, "test"); //绘制文本
}
};

#endif //MYGLWIDGET_H
View Code

下面分别是z_translate为-6、-4、-2、-0.1、-0.09时的效果,可以看到其绝对值越小,即为离眼睛越来越近,所以看起来越大,而如果其绝对值小于gluPerspective()设置的最近位置则就看不见了。而如果将z_translate设为正值的话相当于是在眼睛的后方,这样更不能看见了:

《QT Creator快速入门》第十二章:3D绘图第1张《QT Creator快速入门》第十二章:3D绘图第2张《QT Creator快速入门》第十二章:3D绘图第3张《QT Creator快速入门》第十二章:3D绘图第4张《QT Creator快速入门》第十二章:3D绘图第5张

void glMatrixMode(GLenum mode):将当前矩阵设置成参数所指定的模式,以满足不同绘图所需执行的矩阵变换。glMatrixMode()其实就是对接下来要做什么进行一下声明,参数mode指定哪一个矩阵堆栈是下一个矩阵操作的目标:

GL_MODELVIEW, 对模型视图矩阵堆栈应用随后的矩阵操作。可以在执行此命令后,输出自己的物体图形了。在需要绘制出对象或要对所绘制对象进行几何变换时,需要将变换矩阵设置成模型视图模式;

GL_PROJECTION, 对投影矩阵堆栈应用随后的矩阵操作。可以在执行此命令后,为我们的场景增加透视。当需要对绘制的对象设置某种投影方式时,则需要将变换矩阵设置成投影模式;

GL_TEXTURE, 对纹理矩阵堆栈应用随后的矩阵操作。可以在执行此命令后,为我们的图形增加纹理贴图。在进行纹理映射时,才需要将变换矩阵设置成纹理模式。

void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar):设置矩阵:

fovy是眼睛上下睁开的幅度,角度值,值越小,视野范围越狭小(眯眼),感觉物体越近,值越大,视野范围越宽阔(睁大眼),感觉物体越远;

aspect表示裁剪面的宽w高h比,这个影响到视野的截面有多大。

zNear表示近裁剪面到眼睛的距离,zFar表示远裁剪面到眼睛的距离,注意zNear和zFar不能设置设置为负值(你怎么看到眼睛后面的东西),离眼睛越近东西看起来就越大

《QT Creator快速入门》第十二章:3D绘图第6张

QGLWidget下还有一个renderPixmap()方法,使用它可以获得指定矩形的截图(QPixmap),然后可以使用QPixmap的save()来保存该截图。

还可以设置绘制的时候各个顶点使用的颜色,如下所示:

voidMyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕:使用glClearColor()设置的颜色和glClearDepth()设置的深度缓存
    glLoadIdentity(); //重置模型视图矩阵,这样便将坐标原点移到了窗口中心
GLfloat z_translate = -6.0;
    //void glTranslatef(GLfloat x,GLfloat y,GLfloat z);
    glTranslatef(-2.0, 0.0, z_translate); //将坐标原点左移2.0,内移6.0
glBegin(GL_TRIANGLES); //开始绘制三角形
    //逆时针绘制各顶点
    //void glVertex3f(GLfloat x,GLfloat y,GLfloat z);
    glColor3f(1.0, 0.0, 0.0); //红色
    glVertex3f(0.0, 1.0, 0.0);
    glColor3f(0.0, 1.0, 0.0); //绿色
    glVertex3f(-1.0, -1.0, 0.0);
    glColor3f(0.0, 0.0, 1.0); //蓝色
    glVertex3f(1.0, -1.0, 0.0);
    glEnd();

    glTranslatef(4.0, 0.0, 0.0); //将坐标原点右移4.0
    glBegin(GL_QUADS); //开始绘制四边形
    //顺时针绘制各顶点
    glColor3f(1.0, 1.0, 0.0); //黄色
    glVertex3f(-1.0, 1.0, 0.0);
    glVertex3f(1.0, 1.0, 0.0);
    glVertex3f(1.0, -1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);
    glEnd();
}
View Code

《QT Creator快速入门》第十二章:3D绘图第7张

2、3D效果绘制

下面的代码绘制了一个立方体的三面,使用上、下、左、右、4、6键分别沿X轴向上、向下、沿Y轴向左、向右、沿Z轴向左、向右,使用8和2键进行缩小和放大:

class MyGLWidget : publicQGLWidget
{
public:
    MyGLWidget();
protected:
    void initializeGL()override;
    void resizeGL(int w, int h)override;
    void paintGL()override;

    void keyPressEvent(QKeyEvent*)override;
private:
    GLfloat translate = -6.0, xRot = 0.0, yRot = 0.0, zRot = 0.0;
};
View Code
#include "myglwidget.h"#include<GL/glu.h>#include <QKeyEvent>
MyGLWidget::MyGLWidget()
{

}

voidMyGLWidget::initializeGL()
{
    //void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);
    glClearColor(1.0, 0.0, 0.0, 0.0); //设置清除屏幕时使用的颜色为红色
glShadeModel(GL_SMOOTH); //设置阴影平滑

    //void glClearDepth(GLclampd depth);
    glClearDepth(1.0); //设置深度缓存(深度缓冲区中每个像素需要的值)
glEnable(GL_DEPTH_TEST); //启用深度测试功能,根据坐标的远近自动隐藏被遮住的图形(材料)
}

void MyGLWidget::resizeGL(int w, inth)
{
    glViewport(0, 0, (GLint)w, (GLint)h); //设置视口的大小
glMatrixMode(GL_PROJECTION); //投影矩阵模式
    glLoadIdentity(); //重置当前指定的矩阵为单位矩阵,这样可以将矩阵恢复到初始状态。
    gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //设置透视投影矩阵:视角为45度,纵横比为窗口的纵横比,最近和最远的位置分别为0.1和100
glMatrixMode(GL_MODELVIEW); //设置模型视图矩阵
    glLoadIdentity(); //重置模型视图矩阵
}

voidMyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    //坐标原点沿Z轴移动translate,正数为向屏幕外移,负数为向屏幕内移,向屏幕外移相当于离眼睛越来越近所以更大
    glTranslatef(0.0, 0.0, translate);

    //void glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);
    glRotatef(xRot, 1.0, 0.0, 0.0); //绕X轴旋转到xRot度(正数为逆时针、负数为顺时针), glRotatef(xRot, -1.0, 0.0, 0.0)为绕X轴旋转到xRot度(负数为逆时针、正数为顺时针)
    glRotatef(yRot, 0.0, 1.0, 0.0); //绕Y轴旋转到yRot度
    glRotatef(zRot, 0.0, 0.0, 1.0); //绕Z轴旋转到zRot度
glBegin(GL_QUADS);
    //逆时针(从上往下看)绘制正方体的上面
    glColor3f(1.0, 1.0, 0.0); //黄色
    glVertex3f(1.0, 1.0, 1.0);
    glVertex3f(1.0, 1.0, -1.0);
    glVertex3f(-1.0, 1.0, -1.0);
    glVertex3f(-1.0, 1.0, 1.0);

    //逆时针(从上往下看)绘制正方体的下面
    glColor3f(0.0, 1.0, 0.0); //绿色
    glVertex3f(1.0, -1.0, 1.0);
    glVertex3f(1.0, -1.0, -1.0);
    glVertex3f(-1.0, -1.0, -1.0);
    glVertex3f(-1.0, -1.0, 1.0);

    //逆时针绘制正方体的前面
    glColor3f(0.0, 0.0, 1.0); //蓝色
    glVertex3f(1.0, 1.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glVertex3f(1.0, -1.0, 1.0);

    glEnd();
}

void MyGLWidget::keyPressEvent(QKeyEvent* event)
{
    switch (event->key()) {
        caseQt::Key_Up:
            xRot -= 10;
            break;
        caseQt::Key_Down:
            xRot += 10;
            break;
        caseQt::Key_Left:
            yRot -= 10;
            break;
        caseQt::Key_Right:
            yRot += 10;
            break;
        caseQt::Key_4:
            zRot += 10;
            break;
        caseQt::Key_6:
            zRot -= 10;
            break;
        caseQt::Key_8:
            if(--translate <= -20)
                translate = -1;
            break;
        caseQt::Key_2:
            if(++translate >= -1)
                translate = -20;
            break;
    }
    updateGL(); //更新绘制
QGLWidget::keyPressEvent(event);
}
View Code

《QT Creator快速入门》第十二章:3D绘图第8张《QT Creator快速入门》第十二章:3D绘图第9张《QT Creator快速入门》第十二章:3D绘图第10张《QT Creator快速入门》第十二章:3D绘图第11张《QT Creator快速入门》第十二章:3D绘图第12张《QT Creator快速入门》第十二章:3D绘图第13张《QT Creator快速入门》第十二章:3D绘图第14张《QT Creator快速入门》第十二章:3D绘图第15张《QT Creator快速入门》第十二章:3D绘图第16张

3、使用纹理贴图

使用纹理贴图可以参考Qt中的Textures示例程序。

#include <QGLWidget>

class MyGLWidget : publicQGLWidget
{
public:
    MyGLWidget();
protected:
    void initializeGL()override;
    void resizeGL(int w, int h)override;
    void paintGL()override;

    void keyPressEvent(QKeyEvent*)override;
private:
    GLfloat translate = -6.0, xRot = 0.0, yRot = 0.0, zRot = 0.0;
    GLuint textures[3]; //存储纹理
};
View Code
voidMyGLWidget::initializeGL()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);

    //创建并绑定纹理
    textures[0] = bindTexture(QPixmap("F://side1.png"));
    textures[1] = bindTexture(QPixmap("F://side2.png"));
    textures[2] = bindTexture(QPixmap("F://side3.png"));

    glEnable(GL_TEXTURE_2D); //开启2D纹理贴图功能
}

......

voidMyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(0.0, 0.0, translate);
    glRotatef(xRot, 1.0, 0.0, 0.0);
    glRotatef(yRot, 0.0, 1.0, 0.0);
    glRotatef(zRot, 0.0, 0.0, 1.0);

    //绘制正方体的上面
    glBindTexture(GL_TEXTURE_2D, textures[2]); //绑定纹理
    glBegin(GL_QUADS); //更改使用的纹理必须再次使用glBegin()来开始一个新的绘图
    //void glTexCoord2f(GLfloat s,GLfloat t); //设置纹理的坐标,应该在每次绘制顶点前调用它,纹理的四个顶点应该与四边形四个顶点正确对应
    glTexCoord2f(1.0, 0.0); //第一个参数是X坐标(0.0为纹理的最左侧,1.0为纹理的最右侧),第二个参数是Y坐标(0.0为纹理的底部,1.0为纹理的顶部)
    glVertex3f(1.0, 1.0, 1.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, -1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, 1.0, -1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glEnd();

    //绘制正方体的下面
    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glBegin(GL_QUADS);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, 1.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, -1.0, -1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, -1.0, -1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glEnd();

    //绘制正方体的前面
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, 1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, 1.0);
    glEnd();
}

......
View Code

《QT Creator快速入门》第十二章:3D绘图第17张《QT Creator快速入门》第十二章:3D绘图第18张《QT Creator快速入门》第十二章:3D绘图第19张

可以看到图形下面的2看起来是倒置的,因为我们绘制的时候是从上往下看的,将纹理的(0.0, 0.0)顶点和(0.0, 1.0)顶点对置、(1.0, 0.0)顶点和(1.0, 1.0)顶点对置即可,如下所示:

......

    //绘制正方体的下面
    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glBegin(GL_QUADS);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, -1.0, 1.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, -1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, -1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glEnd();
    
    ......
View Code

《QT Creator快速入门》第十二章:3D绘图第20张

4、在3D场景中绘制2D图形

QGLWidget可以实现3D场景绘图,而QGLWidget也是一个QWidget部件,所以也可以进行2D绘图,可以参考Overpainting示例程序。如下所示的示例先在构造函数中调用setAutoFillBackground(),然后在keyPressEvent()中将updateGL()替换为update(),然后将initializeGL()、resizeGL()、paintGL()中代码剪切到新的方法中后在paintEvent()方法中添加对它们的调用:

class MyGLWidget : publicQGLWidget
{
public:
    MyGLWidget();
protected:
    void initializeGL()override;
    void resizeGL(int w, int h)override;
    void paintGL()override;
    void keyPressEvent(QKeyEvent*)override;

    void paintEvent(QPaintEvent*)override;
    voidinitializeGL2();
    void resizeGL2(int w, inth);
    voidpaintGL2();
private:
    GLfloat translate = -6.0, xRot = 0.0, yRot = 0.0, zRot = 0.0;
    GLuint textures[3];
};
View Code
MyGLWidget::MyGLWidget()
{
    setAutoFillBackground(false); //关闭自动填充背景
}

voidMyGLWidget::initializeGL()
{

}

void MyGLWidget::resizeGL(int w, inth)
{

}

voidMyGLWidget::paintGL()
{

}

voidMyGLWidget::initializeGL2()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);

    textures[0] = bindTexture(QPixmap("F://side1.png"));
    textures[1] = bindTexture(QPixmap("F://side2.png"));
    textures[2] = bindTexture(QPixmap("F://side3.png"));
    glEnable(GL_TEXTURE_2D);
}

void MyGLWidget::resizeGL2(int w, inth)
{
    glViewport(0, 0, (GLint)w, (GLint)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (GLint)w / (GLint)h, 0.1, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

voidMyGLWidget::paintGL2()
{
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(0.0, 0.0, translate);
    glRotatef(xRot, 1.0, 0.0, 0.0);
    glRotatef(yRot, 0.0, 1.0, 0.0);
    glRotatef(zRot, 0.0, 0.0, 1.0);

    glBindTexture(GL_TEXTURE_2D, textures[2]);
    glBegin(GL_QUADS);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, 1.0, 1.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, -1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, 1.0, -1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glEnd();

    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glBegin(GL_QUADS);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, 1.0);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, -1.0, -1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, -1.0, -1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glEnd();

    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(1.0, 1.0);
    glVertex3f(1.0, 1.0, 1.0);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1.0, -1.0, 1.0);
    glTexCoord2f(1.0, 0.0);
    glVertex3f(1.0, -1.0, 1.0);
    glEnd();
}

void MyGLWidget::keyPressEvent(QKeyEvent* event)
{
    switch (event->key()) {
        caseQt::Key_Up:
            xRot -= 10;
            break;
        caseQt::Key_Down:
            xRot += 10;
            break;
        caseQt::Key_Left:
            yRot -= 10;
            break;
        caseQt::Key_Right:
            yRot += 10;
            break;
        caseQt::Key_4:
            zRot += 10;
            break;
        caseQt::Key_6:
            zRot -= 10;
            break;
        caseQt::Key_8:
            if(--translate <= -20)
                translate = -1;
            break;
        caseQt::Key_2:
            if(++translate >= -1)
                translate = -20;
            break;
    }
    update(); //更新绘制
QGLWidget::keyPressEvent(event);
}

void MyGLWidget::paintEvent(QPaintEvent*)
{
    makeCurrent(); //在当前窗口中进行OpenGL的绘制
    glMatrixMode(GL_MODELVIEW); //将模型视图矩阵压入堆栈
glPushMatrix();

    initializeGL2();
    resizeGL2(width(), height());
    paintGL2();

    //关闭启用的功能并弹出模型视图矩阵
glDisable(GL_DEPTH_TEST);
    glDisable(GL_TEXTURE_2D);
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    //进行2D绘图
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setBrush(Qt::yellow);
    painter.drawRect(0, 0, 100, 100);
    painter.end();
}
View Code

《QT Creator快速入门》第十二章:3D绘图第21张

免责声明:文章转载自《《QT Creator快速入门》第十二章:3D绘图》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[Jenkins]Jenkins构建时提示java.io.IOException: No space left on device从0开始 图论学习 邻接表 STL vector下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Core Animation 文档翻译 (第二篇)—核心动画基础要素

前言 核心动画为我们APP内Views动画和其他可视化元素动画提供了综合性的实现体系。核心动画不是我们APP内Views的替代品,相反,它是一种结合Views来提供更好性能和支持Content动画的技术。它通过将Views的Content缓存进可以被绘图软件直接操作处理的Bitmaps来达到这种高性能。在某些情况下,这种缓存技术可能需要我们重新思考我们将...

Android平台下OpenGL初步使用

本文只关注于如何一步步实现在Android平台下运用OpenGl。 1、GLSurfaceView GLSurfaceView是Android应用程序中实现OpenGl画图的重要组成部分。GLSurfaceView中封装了一个Surface。而android平台下关于图像的现实,差不多都是由Surface来实现的。 2、Renderer 有了GLSurfa...

glViewport()函数和glOrtho()函数的理解

在OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho.glOrtho是创建一个正交平行的视景体。 一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情况, glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两...

OSG开源教程(转)

整理:荣明、王伟 北 京 2008年4月 序 第一次接触OSG是在2001年,当时开源社区刚刚兴起,还没有现在这么火。下载了OSG源码,但是在看了几个Demo之后,感觉没有什么特别之处。时隔七年之后,我再次将目光投向OSG,发现OSG确实有其独到之处,很多3D效果已经不弱于甚至超过商业软件,有感于开源力量的巨大。但是,与当前主流3D商业软件如Vega、Ve...

OpenGL的glViewport视口变换函数详解[转]

调用glViewPort函数来决定视见区域,告诉OpenGL应把渲染之后的图形绘制在窗体的哪个部位。当视见区域是整个窗体时,OpenGL将把渲染结果绘制到整个窗口。 voidglViewPort(GLInt x; GLInty; GLSizeiWidth; GLSizeiHeight);     其中,参数X,Y指定了视见区域的左下角在窗口中的位置,一般情...

Qt下载地址

上Qt官网http://www.qt.io/download/想下载Qt,速度很慢,在这里记录下在Qt官网看到的镜像下载地址: 1. 所有Qt版本下载地址: http://download.qt.io/archive/qt/ 2. 所有Qt Creator下载地址: http://download.qt.io/archive/qtcreator/ 3...