Qt|OpenGL-天空盒子的创建

程序运行截图如下:

源码如下:

myglwidget.h

#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H

#include <QOpenGLWidget>
#include <QWidget>
class SkyBox;

class MyGLWidget : public QOpenGLWidget
{
    Q_OBJECT
public:
    explicit MyGLWidget(QWidget *parent = 0);
    SkyBox *m_skybox;
    double m_axle_X;
    double m_axle_Y;
    double m_rotate_value;

    int m_verticalValue;

public slots:

protected:
    void initializeGL();
    void resizeGL(int w,int h);
    void paintGL();
};

#endif // MYGLWIDGET_H

skybox.h

#ifndef SKYBOX_H
#define SKYBOX_H

#include <GL/gl.h>
#include <GL/glu.h>
#include <QString>
class QImage;

class SkyBox
{
public:
    SkyBox();
    void draw();
    void Init();
protected:
    GLuint CreateTexture2DFromBMP(const char*bmpPath);
    unsigned char * LoadFileContent(const char *path, int &filesize);
    unsigned char *DecodeBMP(unsigned char*bmpFileData, int&width, int&height);

    GLuint createTexture2D(unsigned char *piexlData, int width, int height, GLenum type);
private:
    GLuint m_textures[6];

};

#endif // SKYBOX_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

public slots:
    void upBtnClicked();
    void downBtnClicked();
    void leftBtnClicked();
    void rightBtnClicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

myglwidget.cpp

#include "myglwidget.h"
#include <GL/glu.h>
#include <QDebug>
#include "skybox.h"

MyGLWidget::MyGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
    m_skybox=new SkyBox;
    m_axle_X=0.0;
    m_axle_Y=0.0;
    m_rotate_value=0.0;
    m_verticalValue=0;
}

void MyGLWidget::initializeGL()
{
    glMatrixMode(GL_PROJECTION);
    gluPerspective(50.0f,800.0f/600.0f,0.1f,1000.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    m_skybox->Init();
}

void MyGLWidget::resizeGL(int w, int h)
{
    Q_UNUSED(w)
    Q_UNUSED(h)
}

void MyGLWidget::paintGL()
{
    glClearColor(0.0f,0.0f,0.0f,1.0f);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    m_skybox->draw();
    if(m_axle_X==1){
        if(m_verticalValue>=90||m_verticalValue<=-90){
            return;
        }
    }
    glRotatef(m_rotate_value,m_axle_X,m_axle_Y,0.0);
}

skybox.cpp

#include "skybox.h"
#include <QImage>
#include <QDebug>
#include <QFile>

SkyBox::SkyBox()
{

}

void SkyBox::draw()
{
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_textures[0]);
    glBegin(GL_QUADS);
    glColor4ub(255,255,255,255);
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-0.5f,-0.5f,-0.5f);
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(0.5f,-0.5f,-0.5f);
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(0.5f,0.5f,-0.5f);
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-0.5f,0.5f,-0.5f);
    glEnd();
    glBindTexture(GL_TEXTURE_2D, m_textures[1]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(0.5f,-0.5f,0.5f);
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(-0.5f,-0.5f,0.5f);
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(-0.5f,0.5f,0.5f);
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(0.5f,0.5f,0.5f);
    glEnd();
    glBindTexture(GL_TEXTURE_2D, m_textures[2]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-0.5f,-0.5f,0.5f);
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(-0.5f,-0.5f,-0.5f);
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(-0.5f,0.5f,-0.5f);
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-0.5f,0.5f,0.5f);
    glEnd();
    glBindTexture(GL_TEXTURE_2D, m_textures[3]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(0.5f,-0.5f,-0.5f);
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(0.5f,-0.5f,0.5f);
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(0.5f,0.5f, 0.5f);
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(0.5f,0.5f,-0.5f);
    glEnd();
    glBindTexture(GL_TEXTURE_2D, m_textures[4]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-0.5f,0.5f,-0.5f);
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(0.5f,0.5f,-0.5f);
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(0.5f,0.5f,0.5f);
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-0.5f,0.5f,0.5f);
    glEnd();
    glBindTexture(GL_TEXTURE_2D,m_textures[5]);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);
    glVertex3f(-0.5f,-0.5f,0.5f);
    glTexCoord2f(1.0f,0.0f);
    glVertex3f(0.5f,-0.5f,0.5f);
    glTexCoord2f(1.0f,1.0f);
    glVertex3f(0.5f,-0.5f,-0.5f);
    glTexCoord2f(0.0f,1.0f);
    glVertex3f(-0.5f,-0.5f,-0.5f);
    glEnd();
}

void SkyBox::Init()
{
    m_textures[0]=CreateTexture2DFromBMP("E:\\Qt2018\\SkyOpenGL\\Res\\front.bmp");
    m_textures[1]=CreateTexture2DFromBMP("E:\\Qt2018\\SkyOpenGL\\Res\\back.bmp");
    m_textures[2]=CreateTexture2DFromBMP("E:\\Qt2018\\SkyOpenGL\\Res\\left.bmp");
    m_textures[3]=CreateTexture2DFromBMP("E:\\Qt2018\\SkyOpenGL\\Res\\right.bmp");
    m_textures[4]=CreateTexture2DFromBMP("E:\\Qt2018\\SkyOpenGL\\Res\\top.bmp");
    m_textures[5]=CreateTexture2DFromBMP("E:\\Qt2018\\SkyOpenGL\\Res\\bottom.bmp");
}

GLuint SkyBox::CreateTexture2DFromBMP(const char *bmpPath)
{
    int nFileSize=0;
    unsigned char *bmpFileContent=LoadFileContent(bmpPath,nFileSize);
    if (bmpFileContent==nullptr){
        return 0;
    }
    int bmpWidth=0,bmpHeight=0;
    unsigned char*pixelData=DecodeBMP(bmpFileContent,bmpWidth,bmpHeight);
    if (bmpWidth==0){
        delete bmpFileContent;
        return 0;
    }
    GLuint texture=createTexture2D(pixelData,bmpWidth,bmpHeight,GL_RGB);
    delete bmpFileContent;
    return texture;
}

unsigned char *SkyBox::LoadFileContent(const char *path,int &filesize)
{
    unsigned char*fileContent=nullptr;
    filesize=0;
    FILE*pFile=fopen(path,"rb");
    if(pFile){
        fseek(pFile,0,SEEK_END);
        int nLen=ftell(pFile);
        if(nLen>0){
            rewind(pFile);
            fileContent=new unsigned char[nLen + 1];
            fread(fileContent,sizeof(unsigned char),nLen,pFile);
            fileContent[nLen] ='\0';
            filesize=nLen;
        }
        fclose(pFile);
    }
    return fileContent;
}

unsigned char *SkyBox::DecodeBMP(unsigned char *bmpFileData,int &width,int &height)
{
    if (0x4D42==*((unsigned short*)bmpFileData)){
        int pixelDataOffset=*((int*)(bmpFileData+10));
        width=*((int*)(bmpFileData+18));
        height=*((int*)(bmpFileData+22));
        unsigned char*pixelData=bmpFileData+pixelDataOffset;
        for (int i=0;i<width*height*3;i+=3){
            unsigned char temp=pixelData[i];
            pixelData[i]=pixelData[i+2];
            pixelData[i+2]=temp;
        }
        return pixelData;
    }
    return nullptr;
}

GLuint SkyBox::createTexture2D(unsigned char *piexlData, int width, int height, GLenum type)
{
    GLuint texture;
    glGenTextures(1,&texture);
    glBindTexture(GL_TEXTURE_2D,texture);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
    glTexImage2D(GL_TEXTURE_2D,0,type,width,height,0,type,GL_UNSIGNED_BYTE,piexlData);
    return texture;
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "skybox.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->upPushButton,SIGNAL(clicked(bool)),this,SLOT(upBtnClicked()));
    connect(ui->downPushButton,SIGNAL(clicked(bool)),this,SLOT(downBtnClicked()));
    connect(ui->leftPushButton,SIGNAL(clicked(bool)),this,SLOT(leftBtnClicked()));
    connect(ui->rightPushButton,SIGNAL(clicked(bool)),this,SLOT(rightBtnClicked()));
}

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

void Widget::upBtnClicked()
{
    ui->openGLWidget->m_axle_X=1.0;
    ui->openGLWidget->m_axle_Y=0.0;
    ui->openGLWidget->m_rotate_value=-2.0;
    ui->openGLWidget->m_verticalValue+=1;
    ui->openGLWidget->update();
}

void Widget::downBtnClicked()
{
    ui->openGLWidget->m_axle_X=1.0;
    ui->openGLWidget->m_axle_Y=0.0;
    ui->openGLWidget->m_rotate_value=2.0;
    ui->openGLWidget->m_verticalValue-=1;
    ui->openGLWidget->update();
}

void Widget::leftBtnClicked()
{
    ui->openGLWidget->m_axle_X=0.0;
    ui->openGLWidget->m_axle_Y=1.0;
    ui->openGLWidget->m_rotate_value=-2.0;
    ui->openGLWidget->update();
}

void Widget::rightBtnClicked()
{
    ui->openGLWidget->m_axle_X=0.0;
    ui->openGLWidget->m_axle_Y=1.0;
    ui->openGLWidget->m_rotate_value=2.0;
    ui->openGLWidget->update();
}

猜你喜欢

转载自blog.csdn.net/qq78442761/article/details/81271146
今日推荐