摄像机
一、使用lookat函数处理摄像头问题
widget需要做一些修改,支持按钮wsadqe改变摄像头视角,鼠标左键和滚轮也可以改变位置
#include "widget.h" #include "ui_widget.h" GLuint VBO, VAO, EBO; Widget::Widget() { cameraPos = QVector3D(0.0f, 0.0f, 3.0f); cameraFront = QVector3D(0.0f, 0.0f, -1.0f); cameraUp = QVector3D(0.0f, 1.0f, 0.0f); deltaTime = 0.0f; lastFrame = 0.0f; firstMouse = true; yaw = -90.0f; pitch = 0.0f; lastX = 800.0f / 2.0; lastY = 600.0 / 2.0; fov = 45.0f; } Widget::~Widget() { delete ourShader; core->glDeleteVertexArrays(1, &VAO); core->glDeleteBuffers(1, &VBO); core->glDeleteBuffers(1, &EBO); texture1->destroy(); texture2->destroy(); } void Widget::initializeGL() { //着色器部分 core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>(); if (!core) { qWarning() << "Could not obtain required OpenGL context version"; exit(1); } ourShader = new Shader(":/shader/vertexshadersource.vert", ":/shader/fragmentshadersource.frag"); //VAO,VBO数据部分 float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; GLuint indices[] = { 0, 1, 3, // first triangle 1, 2, 3 // second triangle }; core->glGenVertexArrays(1, &VAO); core->glGenBuffers(1, &VBO); core->glGenBuffers(1, &EBO); core->glBindVertexArray(VAO); core->glBindBuffer(GL_ARRAY_BUFFER, VBO); core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // core->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // core->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //position attribute core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), nullptr); core->glEnableVertexAttribArray(0); //texture coord attribute core->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3 * sizeof(float))); core->glEnableVertexAttribArray(1); //纹理1 texture1 = new QOpenGLTexture(QImage(":/image/box.jpg").mirrored(), QOpenGLTexture::GenerateMipMaps); //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps if(!texture1->isCreated()) { qDebug()<<"Failed to load texture" << endl; } texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat); texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat); texture1->setMinificationFilter(QOpenGLTexture::Linear); texture1->setMagnificationFilter(QOpenGLTexture::Linear); texture1->setFormat(QOpenGLTexture::RGBFormat); texture2 = new QOpenGLTexture(QImage(":/image/smile.png").mirrored(), QOpenGLTexture::GenerateMipMaps); //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps if(!texture2->isCreated()) { qDebug()<<"Failed to load texture" << endl; } texture2->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat); texture2->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat); texture2->setMinificationFilter(QOpenGLTexture::Linear); texture2->setMagnificationFilter(QOpenGLTexture::Linear); texture2->setFormat(QOpenGLTexture::RGBFormat); ourShader->use(); ourShader->shaderProgram.setUniformValue("texture1", 0); ourShader->shaderProgram.setUniformValue("texture2", 1); mtime.start(); core->glEnable(GL_DEPTH_TEST); } QVector3D cubePositions[] = { QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 2.0f, 5.0f, -15.0f), QVector3D(-1.5f, -2.2f, -2.5f), QVector3D(-3.8f, -2.0f, -12.3f), QVector3D( 2.4f, -0.4f, -3.5f), QVector3D(-1.7f, 3.0f, -7.5f), QVector3D( 1.3f, -2.0f, -2.5f), QVector3D( 1.5f, 2.0f, -2.5f), QVector3D( 1.5f, 0.2f, -1.5f), QVector3D(-1.3f, 1.0f, -1.5f) }; void Widget::paintGL() { deltaTime = (GLfloat)mtime.elapsed()/100 - lastFrame; lastFrame = (GLfloat)mtime.elapsed()/100; core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f); core->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ourShader->use(); core->glActiveTexture(GL_TEXTURE1); texture2->bind(); core->glActiveTexture(GL_TEXTURE0); texture1->bind(); QMatrix4x4 view, projection; view.translate(QVector3D(0.0f, 0.0f, -3.0f)); projection.perspective(fov, (GLfloat)width()/(float)height(), 0.1f, 100.0f); ourShader->use(); ourShader->shaderProgram.setUniformValue("view", view); ourShader->shaderProgram.setUniformValue("projection", projection); // ourShader->use(); view.lookAt(cameraPos, cameraPos+cameraFront, cameraUp); ourShader->shaderProgram.setUniformValue("view", view); core->glBindVertexArray(VAO); for(unsigned int i=0;i<10;i++) { QMatrix4x4 model; model.translate(cubePositions[i]); if(i%3 == 0) { float angle = 20.0f*i + (float)mtime.elapsed()/10; model.rotate(angle, QVector3D(0.5f, 1.0f, 0.0f)); } ourShader->shaderProgram.setUniformValue("model", model); core->glDrawArrays(GL_TRIANGLES, 0, 36); } update(); } void Widget::resizeGL(int w, int h) { core->glViewport(0, 0, w, h); } void Widget::keyPressEvent(QKeyEvent *event) { GLfloat cameraSpeed = 2.5 * deltaTime; if(event->key() == Qt::Key_W) { cameraPos -= cameraFront * cameraSpeed; } if(event->key() == Qt::Key_S) { cameraPos += cameraFront * cameraSpeed; } if(event->key() == Qt::Key_A) { cameraPos -= (QVector3D::crossProduct(cameraFront, cameraUp).normalized()) * cameraSpeed; } if(event->key() == Qt::Key_D) { cameraPos += (QVector3D::crossProduct(cameraFront, cameraUp).normalized()) * cameraSpeed; } if(event->key() == Qt::Key_E) { cameraPos += cameraUp * cameraSpeed; } if(event->key() == Qt::Key_Q) { cameraPos -= cameraUp * cameraSpeed; } } void Widget::mouseMoveEvent(QMouseEvent *event) { GLfloat xpos = event->pos().x(); GLfloat ypos = event->pos().y(); if (firstMouse) { lastX = event->pos().x(); lastY = event->pos().y(); firstMouse = false; } GLfloat xoffset = xpos - lastX; GLfloat yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; GLfloat sensitivity = 0.01f; // change this value to your liking xoffset *= sensitivity; yoffset *= sensitivity; yaw += xoffset; pitch += yoffset; // make sure that when pitch is out of bounds, screen doesn't get flipped if (pitch > 89.0f) pitch = 89.0f; if (pitch < -89.0f) pitch = -89.0f; QVector3D front(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)); cameraFront = front.normalized(); } void Widget::wheelEvent(QWheelEvent *event) { QPoint offset = event->angleDelta(); if(fov >= 1.0f && fov <=45.0f) fov -= ((GLfloat)offset.y())/20; if(fov < 1.0f) fov = 1.0f; if(fov > 45.0f) fov = 45.0f; }
h文件中多了一些变量
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QGLWidget> #include <QOpenGLShader> #include <QOpenGLShaderProgram> #include <QDebug> #include <QOpenGLFunctions> #include <QOpenGLFunctions_3_3_Core> #include <QTime> #include <QtMath> #include <QTimer> #include <QOpenGLTexture> #include <QKeyEvent> #include "shader.h" namespace Ui { class Widget; } class Widget : public QGLWidget { Q_OBJECT public: Widget(); ~Widget(); public slots: protected: virtual void initializeGL(); virtual void paintGL(); virtual void resizeGL(int w, int h); virtual void keyPressEvent(QKeyEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void wheelEvent(QWheelEvent *event); private: QOpenGLFunctions_3_3_Core *core; QOpenGLTexture *texture1, *texture2; Shader *ourShader; QTimer updateTimer; QTime mtime; QVector3D cameraPos; QVector3D cameraFront; QVector3D cameraUp; GLfloat deltaTime; GLfloat lastFrame; GLboolean firstMouse; GLfloat yaw; GLfloat pitch; GLfloat lastX; GLfloat lastY; GLfloat fov; }; #endif // WIDGET_H
-
看看你是否能够修改摄像机类,使得其能够变成一个真正的FPS摄像机(也就是说不能够随意飞行);你只能够呆在xz平面上:
void Widget::keyPressEvent(QKeyEvent *event) { GLfloat cameraSpeed = 2.5 * deltaTime; if(event->key() == Qt::Key_W) { cameraPos -= cameraFront * cameraSpeed; } if(event->key() == Qt::Key_S) { cameraPos += cameraFront * cameraSpeed; } if(event->key() == Qt::Key_A) { cameraPos -= (QVector3D::crossProduct(cameraFront, cameraUp).normalized()) * cameraSpeed; } if(event->key() == Qt::Key_D) { cameraPos += (QVector3D::crossProduct(cameraFront, cameraUp).normalized()) * cameraSpeed; } // if(event->key() == Qt::Key_E) { // cameraPos += cameraUp * cameraSpeed; // } // if(event->key() == Qt::Key_Q) { // cameraPos -= cameraUp * cameraSpeed; // } }
-
试着创建你自己的LookAt函数,其中你需要手动创建一个我们在一开始讨论的观察矩阵。用你的函数实现来替换GLM的LookAt函数,看看它是否还能一样地工作:
#ifndef MYCAMERA_H #define MYCAMERA_H #include <QObject> #include <QMatrix4x4> #include <QKeyEvent> #include <QOpenGLShader> #include <QtMath> #include <QDebug> enum Camera_Movement { FORWARD, BACKWARD, LEFT, RIGHT, UP, DOWN }; const GLfloat YAW = -90.0f; const GLfloat PITCH = 0.0f; const GLfloat SPEED = 1.0f; const GLfloat SENSITIVITY = 0.01f; const GLfloat ZOOM = 45.0f; class MyCamera : public QObject { Q_OBJECT public: explicit MyCamera(QVector3D position = QVector3D(0.0f, 0.0f, 0.0f), QVector3D up = QVector3D(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH); QMatrix4x4 getViewMatrix(); //返回lookat函数 void processMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constraintPitch = true);//相应鼠标操作函数 void processMouseScroll(GLfloat yoffset); //鼠标滚轮事件 void processInput(GLfloat dt); //键盘循环函数 QVector3D position; QVector3D worldUp; QVector3D front; QVector3D up; // view坐标系 的上方向 QVector3D right; // view坐标系的 右方向 //Eular Angles GLfloat picth; GLfloat yaw; //Camera options GLfloat movementSpeed; GLfloat mouseSensitivity; GLfloat zoom; //键盘多键触控所需 GLboolean keys[1024]; private: void updateCameraVectors(); void processKeyboard(Camera_Movement direction, GLfloat deltaTime);//键盘处理事件函数 }; #endif // MYCAMERA_H
myCamera.cpp
#include "mycamera.h" MyCamera::MyCamera(QVector3D position, QVector3D up, GLfloat yaw, GLfloat pitch) : front(QVector3D(0.0f, 0.0f, -1.0f)), movementSpeed(SPEED), mouseSensitivity(SENSITIVITY), zoom(ZOOM) { this->position = position; this->worldUp = up; this->yaw = yaw; this->picth = pitch; this->updateCameraVectors(); for(GLuint i = 0; i != 1024; ++i) keys[i] = GL_FALSE; } QMatrix4x4 MyCamera::getViewMatrix() { QMatrix4x4 view; view.lookAt(this->position, this->position + this->front, this->up); return view; } void MyCamera::processMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constraintPitch) { xoffset *= this->mouseSensitivity; yoffset *= this->mouseSensitivity; this->yaw += xoffset; this->picth += yoffset; if (constraintPitch) { if (this->picth > 89.0f) this->picth = 89.0f; if (this->picth < -89.0f) this->picth = -89.0f; } this->updateCameraVectors(); } void MyCamera::processMouseScroll(GLfloat yoffset) { if (this->zoom >= 1.0f && this->zoom <= 45.0f) this->zoom -= yoffset; if (this->zoom > 45.0f) this->zoom = 45.0f; if (this->zoom < 1.0f) this->zoom = 1.0f; } void MyCamera::processInput(GLfloat dt) { if (keys[Qt::Key_W]) processKeyboard(FORWARD, dt); if (keys[Qt::Key_S]) processKeyboard(BACKWARD, dt); if (keys[Qt::Key_A]) processKeyboard(LEFT, dt); if (keys[Qt::Key_D]) processKeyboard(RIGHT, dt); if (keys[Qt::Key_E]) processKeyboard(UP, dt); if (keys[Qt::Key_Q]) processKeyboard(DOWN, dt); } void MyCamera::updateCameraVectors() { QVector3D front3(qCos(this->yaw) * qCos(this->picth), qSin(this->picth), qSin(this->yaw) * qCos(this->picth)); this->front = front3.normalized(); this->right = QVector3D::crossProduct(this->front, this->worldUp).normalized(); this->up = QVector3D::crossProduct(this->right, this->front).normalized(); } void MyCamera::processKeyboard(Camera_Movement direction, GLfloat deltaTime) { GLfloat velocity = this->movementSpeed * deltaTime; if (direction == FORWARD) this->position += this->front * velocity; if (direction == BACKWARD) this->position -= this->front * velocity; if (direction == LEFT) this->position -= this->right * velocity; if (direction == RIGHT) this->position += this->right * velocity; if (direction == UP) this->position += this->worldUp * velocity; if (direction == DOWN) this->position -= this->worldUp * velocity; }
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QGLWidget> #include <QOpenGLShader> #include <QOpenGLShaderProgram> #include <QDebug> #include <QOpenGLFunctions> #include <QOpenGLFunctions_3_3_Core> #include <QTime> #include <QtMath> #include <QTimer> #include <QOpenGLTexture> #include <QKeyEvent> #include "shader.h" #include "mycamera.h" namespace Ui { class Widget; } class Widget : public QGLWidget { Q_OBJECT public: Widget(); ~Widget(); public slots: protected: virtual void initializeGL(); virtual void paintGL(); virtual void resizeGL(int w, int h); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void mouseMoveEvent(QMouseEvent *event); void wheelEvent(QWheelEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private: QOpenGLFunctions_3_3_Core *core; QOpenGLTexture *texture1, *texture2; Shader *ourShader; // QTimer updateTimer; QTime mtime; MyCamera *camera; // QVector3D cameraPos; // QVector3D cameraFront; // QVector3D cameraUp; GLfloat deltaTime; GLfloat lastFrame; GLboolean isFirstMouse; GLboolean isLeftMousePress; // GLfloat yaw; // GLfloat pitch; // GLfloat fov; GLfloat lastX; GLfloat lastY; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" GLuint VBO, VAO, EBO; Widget::Widget() { deltaTime = 0.0f; lastFrame = 0.0f; lastX = 800.0f / 2.0; lastY = 600.0 / 2.0; } Widget::~Widget() { delete ourShader; core->glDeleteVertexArrays(1, &VAO); core->glDeleteBuffers(1, &VBO); core->glDeleteBuffers(1, &EBO); texture1->destroy(); texture2->destroy(); delete camera; } void Widget::initializeGL() { //着色器部分 core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>(); if (!core) { qWarning() << "Could not obtain required OpenGL context version"; exit(1); } ourShader = new Shader(":/shader/vertexshadersource.vert", ":/shader/fragmentshadersource.frag"); //VAO,VBO数据部分 float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; core->glGenVertexArrays(1, &VAO); core->glGenBuffers(1, &VBO); core->glBindVertexArray(VAO); core->glBindBuffer(GL_ARRAY_BUFFER, VBO); core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //position attribute core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), nullptr); core->glEnableVertexAttribArray(0); //texture coord attribute core->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3 * sizeof(float))); core->glEnableVertexAttribArray(1); //纹理1 texture1 = new QOpenGLTexture(QImage(":/image/box.jpg").mirrored(), QOpenGLTexture::GenerateMipMaps); //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps if(!texture1->isCreated()) { qDebug()<<"Failed to load texture" << endl; } texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat); texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat); texture1->setMinificationFilter(QOpenGLTexture::Linear); texture1->setMagnificationFilter(QOpenGLTexture::Linear); texture1->setFormat(QOpenGLTexture::RGBFormat); //第二张笑脸 texture2 = new QOpenGLTexture(QImage(":/image/smile.png").mirrored(), QOpenGLTexture::GenerateMipMaps); //直接生成绑定一个2d纹理, 并生成多级纹理MipMaps if(!texture2->isCreated()) { qDebug()<<"Failed to load texture" << endl; } texture2->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat); texture2->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat); texture2->setMinificationFilter(QOpenGLTexture::Linear); texture2->setMagnificationFilter(QOpenGLTexture::Linear); texture2->setFormat(QOpenGLTexture::RGBFormat); ourShader->use(); ourShader->shaderProgram.setUniformValue("texture1", 0); ourShader->shaderProgram.setUniformValue("texture2", 1); mtime.start(); core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f); core->glEnable(GL_DEPTH_TEST); //初试化相机 camera = new MyCamera(QVector3D(0.0f, 0.0f, 3.0f)); deltaTime = 0.0f; lastFrame = 0.0f; isFirstMouse = GL_TRUE; isLeftMousePress = GL_FALSE; lastX = width() / 2.0f; lastY = height() / 2.0f; } QVector3D cubePositions[] = { QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 2.0f, 5.0f, -15.0f), QVector3D(-1.5f, -2.2f, -2.5f), QVector3D(-3.8f, -2.0f, -12.3f), QVector3D( 2.4f, -0.4f, -3.5f), QVector3D(-1.7f, 3.0f, -7.5f), QVector3D( 1.3f, -2.0f, -2.5f), QVector3D( 1.5f, 2.0f, -2.5f), QVector3D( 1.5f, 0.2f, -1.5f), QVector3D(-1.3f, 1.0f, -1.5f) }; void Widget::paintGL() { GLfloat currentFrame = (GLfloat)mtime.elapsed()/100; deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; camera->processInput(deltaTime); core->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ourShader->use(); core->glActiveTexture(GL_TEXTURE0); texture2->bind(); core->glActiveTexture(GL_TEXTURE1); texture1->bind(); QMatrix4x4 view, projection; view.translate(QVector3D(0.0f, 0.0f, -3.0f)); projection.perspective(camera->zoom, (GLfloat)width()/(GLfloat)height(), 0.1f, 200.f); ourShader->use(); ourShader->shaderProgram.setUniformValue("view", camera->getViewMatrix()); ourShader->shaderProgram.setUniformValue("projection", projection); for(GLuint i=0;i<10;i++) { QMatrix4x4 model; model.translate(cubePositions[i]); model.rotate(20.0f*i, cubePositions[i]); ourShader->shaderProgram.setUniformValue("model", model); core->glBindVertexArray(VAO); core->glDrawArrays(GL_TRIANGLES, 0, 36); } update(); } void Widget::resizeGL(int w, int h) { core->glViewport(0, 0, w, h); } void Widget::keyPressEvent(QKeyEvent *event) { GLuint key = event->key(); if(key >= 0 && key<1024) camera->keys[key] = GL_TRUE; } void Widget::keyReleaseEvent(QKeyEvent *event) { GLuint key = event->key(); if(key >= 0 && key < 1024) camera->keys[key] = GL_FALSE; } void Widget::mouseMoveEvent(QMouseEvent *event) { GLfloat xpos = event->pos().x(); GLfloat ypos = event->pos().y(); if(isLeftMousePress){ if (isFirstMouse){ lastX = xpos; lastY = ypos; isFirstMouse = GL_FALSE; } GLint xoffset = xpos - lastX; GLint yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera->processMouseMovement(xoffset, yoffset); } } void Widget::wheelEvent(QWheelEvent *event) { QPoint offset = event->angleDelta(); camera->processMouseScroll(offset.y()/20.0f); } void Widget::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton){ //注意是button()不是buttons(); isLeftMousePress = GL_TRUE; } } void Widget::mouseReleaseEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton){ //注意是button()不是buttons(); isLeftMousePress = GL_FALSE; isFirstMouse = GL_TRUE; } }
无欲速,无见小利。欲速,则不达;见小利,则大事不成。