QT5 OpenGL(六)立体贴图

1.代码部分

OPenGL.pro

QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = OPenGL12
TEMPLATE = app


SOURCES += main.cpp\
    openglwidget.cpp

HEADERS  += \
    openglwidget.h

LIBS += -lopengl32

OpenglWidget.h

#ifndef OPENGLWIDGET_H
#define OPENGLWIDGET_H
#include <QtOpenGL>

class OpenglWidget : public QGLWidget
{
public:
    OpenglWidget(QWidget *parent=0);
protected:
    void initializeGL();
    void initWidget();
    void paintGL();
    void resizeGL(int width, int height);

private:
    GLfloat mx;
    GLfloat my;
    GLfloat mz;
    GLfloat m_rotateTriangle;
    GLuint *textur;
};

#endif // OPENGLWIDGET_H

OpenglWidget.cpp

#include "openglwidget.h"

OpenglWidget::OpenglWidget(QWidget *parent):QGLWidget(parent)
{
	mx = 0;
	my = 0;
	mz = 0;
    initWidget();
    initializeGL();
}
void OpenglWidget::initializeGL()
{
    //加载图片
    QImage mpic;
    QImage newPic;
    mpic.load("D://Documents//OPenGL12//haha.jpg");
    newPic=QGLWidget::convertToGLFormat(mpic);
    glGenTextures(1,&textur[0]);
    glBindTexture(GL_TEXTURE_2D,textur[0]);

    glTexImage2D(GL_TEXTURE_2D,0,3,newPic.width(),newPic.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,newPic.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);


    QImage mpic1;
    QImage newPic1;
    mpic1.load("D://Documents//OPenGL12//haha1.jpg");
    newPic1=QGLWidget::convertToGLFormat(mpic1);
    glGenTextures(1,&textur[1]);
    glBindTexture(GL_TEXTURE_2D,textur[1]);

    glTexImage2D(GL_TEXTURE_2D,0,3,newPic1.width(),newPic1.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,newPic1.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);




    //启动纹理,负责会全为白色
    glEnable(GL_TEXTURE_2D);

    //设置着色模式,平滑的
    glShadeModel(GL_SMOOTH);
    //清除掉之前的所有颜色
    glClearColor(0.0,0.0,0.0,0.5);
    //深度缓存,设置初始值为1.0,小于1.0的部分是可见的
    glClearDepth(1.0);
    //启动OPenGL的相关功能,由参数决定,这里指
    //(启用了之后,OpenGL在绘制的时候就会检查,当前像素前面是否有别的像素,如果别的像素挡道了它,那它就不会绘制,也就是说,OpenGL就只绘制最前面的一层)
    glEnable(GL_DEPTH_TEST);
    //制定深度缓存比较值
    //这里参数指的是如果输入的深度值小于或者等于参考值则通过
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

}

void OpenglWidget::initWidget()
{
    //从屏幕上(400,400)为起始点,显示一个640*400的界面
    setGeometry(400,200,640,480);
    setWindowTitle("My OPenGL");
}

void OpenglWidget::paintGL()
{
    //清除颜色缓冲和深度缓冲
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    //将当前点移置屏幕中心,相当于复位的操作
    glLoadIdentity();
    //平移函数,参数指的是分别从X轴,Y轴,Z轴平移
    glTranslatef(-1.5,0.0,-6.0);

    glRotatef( mx,1.0,  0.0,0.0 );
    glRotatef(my,0.0,1.0,0.0 );
    glRotatef(mz,0.0,0.0,1.0 );


    glBindTexture( GL_TEXTURE_2D, textur[0] );

    glBegin( GL_QUADS );

    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );
    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( 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 );

    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 );
    glTexCoord2f( 1.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 );
    glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0,  1.0 );

    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 );

    glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 );
    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 );

    glEnd();


    glLoadIdentity();
    glTranslatef(  1.5,  0.0, -6.0 );
    glBindTexture( GL_TEXTURE_2D, textur[1] );

    glRotatef( m_rotateTriangle,  0.0,  1.0,  0.0 );
    glBegin(GL_TRIANGLES);
    glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 );
    glTexCoord2f( 0, 0 ); glVertex3f(  1, -1, 1 );
    glTexCoord2f( 1, 0 ); glVertex3f(  -1, -1, 1 );

    glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 );
    glTexCoord2f( 0, 0 ); glVertex3f( -1.0,  -1.0, 1.0 );
    glTexCoord2f( 1, 0 ); glVertex3f(  -1.0,  -1.0, -1.0 );

    glTexCoord2f( 1, 1 ); glVertex3f( 0,  1, 0 );
    glTexCoord2f( 0, 0 ); glVertex3f( -1.0,  -1.0,  -1.0 );
    glTexCoord2f( 1, 0 ); glVertex3f(  1.0,  -1.0,  -1.0 );

    glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 );
    glTexCoord2f( 0, 0 ); glVertex3f(  1.0, -1.0, -1.0 );
    glTexCoord2f( 1, 0 ); glVertex3f(  1.0, -1.0,  1.0 );

    glTexCoord2f( 0, 0 ); glVertex3f(  -1.0, -1.0, -1.0 );
    glTexCoord2f( 1, 0 ); glVertex3f(  1.0, -1.0,  -1.0 );
    glTexCoord2f( 1, 1 ); glVertex3f(  1.0, -1.0, 1.0 );

    glTexCoord2f( 1, 0 ); glVertex3f(  1.0, -1.0,  -1.0 );
    glTexCoord2f( 1, 1 ); glVertex3f(  1.0, -1.0, 1.0 );
    glTexCoord2f( 0, 1 ); glVertex3f(  -1.0, -1.0,  1.0 );

    glTexCoord2f( 1, 1 ); glVertex3f(  1.0, -1.0, 1.0 );
    glTexCoord2f( 0, 1 ); glVertex3f(  -1.0, -1.0,  1.0 );
    glTexCoord2f( 0, 0 ); glVertex3f(  -1.0, -1.0, -1.0 );
    glEnd();


    mx+=70;
    my+=0;
    mz+=0;
    m_rotateTriangle+=10;
}

void OpenglWidget::resizeGL(int width, int height)
{
    if(0==height)
        height=1;
    //告诉绘制到窗体的哪个位置
    glViewport(0,0,width,height);
    // 设置矩阵模式,参数是设置为投影矩阵
    glMatrixMode(GL_PROJECTION);
    //复位操作
    glLoadIdentity();

    GLdouble aspectRatio=(GLfloat)width/(GLfloat)height;
    GLdouble rFov=45.0*3.14159265/180.0;
    GLdouble zNear=0.1;
    GLdouble zFar=100.0;
    //调用glFrustum,生成矩阵与当前矩阵相乘,生成透视效果
    glFrustum(-zNear*tan(rFov/2.0)*aspectRatio,
              zNear*tan(rFov/2.0)*aspectRatio,
              -zNear*tan(rFov/2.0),
              zNear*tan(rFov/2.0),
              zNear,zFar);
    //切回模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    //复位
    glLoadIdentity();
}

2.注意

glTexCoord2f( x, y ); 
glVertex3f( x, y, z );

    glTexCoord2f这个用于表示原图片的坐标,这样更容易理解,就是以 在x,y 轴的平面里面,(0,0)表示图片的左下角, (0,1)表示左上角,(1,1)表示右上角,(1,0)表示右下角。而对应的glVertex3f则对应为 (-1, -1) , (-1, 1) , (1, 1), (1, -1)。我们怎么来理解这种对应关系呢?那就需要贴图的坐标必须一一对应,就是我们如果顺时针写, 对应的坐都要顺时针,如果逆时针写,对应的坐标都要逆时针一一对应。

    我们的贴图是一张图片,所以它一定是一个平面。 所以坐标从(0,0)开始,这个容易使用。而我们需要贴图的立体图形,虽然每个面是平面图形,但它在坐标系中,始终以立体图形的中心为坐标原点,所以,它是一个三维坐标,三维坐标与二维的对应,就只有以相同的平面顶点旋转顺序来对应了。

3.程序运行结果


猜你喜欢

转载自blog.csdn.net/qq_35703848/article/details/79821967
Qt5
今日推荐