opengl绝无仅有的漫游程序qt专用

来源:互联网 发布:js验证是否是数字 编辑:程序博客网 时间:2024/04/27 22:57

mywidget.h

#ifndef MYWIDGET_H

#define MYWIDGET_H
#include <QGLWidget>
#include <qgl.h>
#include <QKeyEvent>
#include <qtimer.h>
#include <QWidget>
class myWidget : public QGLWidget
{
     Q_OBJECT
public:
    myWidget(QWidget *parent = 0);
    ~myWidget();
protected:
    void initializeGL();
    void resizeGL(int width,int height);
    void paintGL();
    void keyPressEvent(QKeyEvent *event);
    void loadGLTextures();
    void DrawGround();
    void DrawWall();
    void DisplayScene();
protected slots:
    void eddy();
private:
    int size0;
    GLdouble g_eye[3];//
    GLdouble g_look[3];//
    float rad_xz;//角度
    float g_Angle;//左右转
    float g_elev;//仰俯角
    GLuint texture[1];
    GLfloat yRot;
    QTimer *time;
};
#endif // MYWIDGET_H
 
mywidget.cpp:
#include "mywidget.h"
#include <math.h>
#include <qdebug.h>
#include <time.h>
#define MAP 3
myWidget::myWidget(QWidget *parent)
    :QGLWidget(parent)
{
    this->setGeometry(100,100,500,500);
    //this->setMinimumSize(500,500);
    //this->setMaximumSize(500,500);
    size0 = MAP*2;
    g_eye[0]= MAP;//
    g_eye[2]=-MAP;//
    g_Angle=0;//方位角
    g_elev=0;//俯仰角
    g_eye[1] =0.3;//设置摄像机对地位置高
    //摄像机的方向
    g_look[0] = float(g_eye[0] + 100*cos(rad_xz));
    g_look[2] = float(g_eye[2] + 100*sin(rad_xz));
    g_look[1] = g_eye[1];
    //建立modelview矩阵方向
    yRot = 0.0;
    this->time  = new QTimer;
    connect( time, SIGNAL(timeout()),this, SLOT(eddy()) );
    time->start(10);
}
myWidget::~myWidget()
{
}
void myWidget::eddy()
{
   yRot += 5;
   if (yRot == 360)
       yRot = 0;
   updateGL();
}
void myWidget::initializeGL()
{
    loadGLTextures();
    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);
    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.0,0.0,0.0, 0.0);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
}
void myWidget::resizeGL(int width,int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    GLfloat x = GLfloat(width)/GLfloat(height);
    gluPerspective(45.0,x, 0.1,1000.0 );
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
void myWidget::paintGL()
{
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glColor3f(1.0,0.0,0.0);
     glLoadIdentity();
     gluLookAt(g_eye[0],g_eye[1],g_eye[2],g_look[0],g_look[1]+g_elev,g_look[2],0.0,1.0,0.0);
     DrawWall();
     DrawGround();
}
void myWidget::DrawGround()
{
    glPushAttrib(GL_CURRENT_BIT);//保存现有颜色属实性
    glEnable(GL_BLEND);//使用纹理
    glPushMatrix();
    glTranslatef(0,0.0f,-9.0);//平台的定位
    glColor3f(0.0,1.0,0.0);
    glBegin(GL_LINES);//划一界线
    for (int x = -size0*100; x < size0*100;x+=1)
            {glVertex3i(x, 0, -size0); glVertex3i(x, 0,  size0);}
    for (int z = -size0*100; z < size0*100;z+=1)
            {glVertex3i(-size0, 0, z); glVertex3i( size0, 0, z);}
    glEnd();
    glPopMatrix();
    glDisable(GL_BLEND);
}
void myWidget::DrawWall()
{
    glColor3f(1.0,1.0,1.0);
    glPushMatrix();
    glBindTexture( GL_TEXTURE_2D,texture[0]);
      glTranslatef(0.0,0.0,-10);
      glRotatef(yRot,0.0,1.0,0.0);
      glBegin(GL_QUADS);
        glTexCoord2f( 0.0, 0.0 );glVertex3f(-20,0,0);
        glTexCoord2f( 1.0, 0.0 );glVertex3f(20,0,0);
        glTexCoord2f( 1.0, 1.0 );glVertex3f(20,10,0);
        glTexCoord2f( 0.0, 1.0 );glVertex3f(-20,10,0);
      glEnd();
    glPopMatrix();
}
void myWidget::loadGLTextures()
{
    QImage tex, buf;
    if ( !buf.load( ":/bkg.jpg" ) )
    {
        qWarning( "Could not read image file, using single-color instead." );
        return;
    }
    tex = QGLWidget::convertToGLFormat( buf );
    glGenTextures( 1, &texture[0] );
    glBindTexture( GL_TEXTURE_2D, texture[0] );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
        GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() );
}
void myWidget::keyPressEvent(QKeyEvent *event)
{
    float speed = 0.1;
    if (event->key() == Qt::Key_Left)
    {
        g_Angle -= speed*10;
    }
    else if (event->key() == Qt::Key_Right)
    {
        g_Angle += speed*10;
    }
    rad_xz = float(3.14159*g_Angle/180.0f);
    if (event->key() == Qt::Key_Up)
    {
        g_eye[2]+=sin(rad_xz)*speed;
        g_eye[0]+=cos(rad_xz)*speed;
    }
    else if (event->key() == Qt::Key_Down)
    {
        g_eye[2]-=sin(rad_xz)*speed;
        g_eye[0]-=cos(rad_xz)*speed;
    }
    else if (event->key() == Qt::Key_PageUp)//抬头
    {
        g_elev += 0.001;
    }
    else if (event->key() == Qt::Key_PageDown)
    {
         g_elev -= 0.001;
    }
    g_look[0] = float(g_eye[0] + 0.01*cos(rad_xz));
    g_look[2] = float(g_eye[2] + 0.01*sin(rad_xz));
    g_look[1] = g_eye[1];
    //建立modelview矩阵方向
    gluLookAt(g_eye[0],g_eye[1],g_eye[2],g_look[0],g_look[1]+g_elev,g_look[2],0.0,1.0,0.0);
    updateGL();
    qDebug()<<"g_eye:"<<g_eye[0]<<g_eye[1]<<g_eye[2]<<";"<<"\n"<<"g_look"<<g_look[0]<<g_look[1]<<g_look[2];
}
原创粉丝点击