光照--颜色
https://www.jianshu.com/p/bc40f5bd60f3
https://learnopengl-cn.github.io/02%20Lighting/01%20Colors/
#include "lightwidget.h" #include <QDebug> #include <QTimer> // lighting static QVector3D lightPos(1.2f, 1.0f, 2.0f); LightWidget::LightWidget(QWidget *parent) : QOpenGLWidget(parent), vbo(QOpenGLBuffer::VertexBuffer) { m_camera = new ACamera(QVector3D(5.0f,0.0f,10.0f)); m_bLeftPressed = false; m_pTimer = new QTimer(this); connect(m_pTimer,&QTimer::timeout,this,[=]{ m_nTimeValue += 1; update(); }); m_pTimer->start(40); } LightWidget::~LightWidget() { makeCurrent(); vbo.destroy(); if (m_camera != nullptr){ delete m_camera; } doneCurrent(); } void LightWidget::initializeGL() { this->initializeOpenGLFunctions(); createShader(); //VAO,VBO data float vertices[] = { -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, }; vbo.create(); vbo.bind(); vbo.allocate(vertices, sizeof(vertices)); { QOpenGLVertexArrayObject::Binder vaoBind(&cubeVAO); //position attribute int attr = -1; attr = lightingShader.attributeLocation("aPos"); lightingShader.setAttributeBuffer(attr, GL_FLOAT, 0, 3, sizeof(GLfloat) * 3); lightingShader.enableAttributeArray(attr); // glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // glEnableVertexAttribArray(0); } { QOpenGLVertexArrayObject::Binder vaoBind(&lightVAO); // position attribute int attr = -1; attr = lampShader.attributeLocation("aPos"); lampShader.setAttributeBuffer(attr, GL_FLOAT, 0, 3, sizeof(GLfloat) * 3); lampShader.enableAttributeArray(attr); // glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // glEnableVertexAttribArray(0); } vbo.release(); // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); } void LightWidget::resizeGL(int w, int h) { glViewport(0,0,w,h); } void LightWidget::paintGL() { m_camera->processInput(1.0f); glClearColor(0.1f,0.1f,0.1f,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // be sure to activate shader when setting uniforms/drawing objects lightingShader.bind(); lightingShader.setUniformValue("objectColor", QVector3D(1.0f, 0.5f, 0.31f)); lightingShader.setUniformValue("lightColor", QVector3D(1.0f, 1.0f, 1.0f)); // view/projection transformations QMatrix4x4 projection; projection.perspective(m_camera->zoom, 1.0f * width() / height(), 0.1f, 100.0f); QMatrix4x4 view = m_camera->getViewMatrix(); lightingShader.setUniformValue("projection", projection); lightingShader.setUniformValue("view", view); // world transformation QMatrix4x4 model; lightingShader.setUniformValue("model", model); {// render the cube QOpenGLVertexArrayObject::Binder vaoBind(&cubeVAO); glDrawArrays(GL_TRIANGLES, 0, 36); } lightingShader.release(); // also draw the lamp object lampShader.bind(); lampShader.setUniformValue("projection", projection); lampShader.setUniformValue("view", view); model = QMatrix4x4(); model.translate(lightPos); model.scale(0.2f); // a smaller cube lampShader.setUniformValue("model", model); { QOpenGLVertexArrayObject::Binder vaoBind(&lightVAO); glDrawArrays(GL_TRIANGLES, 0, 36); } lampShader.release(); } bool LightWidget::createShader() { bool success = lightingShader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/colors.vert"); if (!success) { qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lightingShader.log(); return success; } success = lightingShader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/colors.frag"); if (!success) { qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lightingShader.log(); return success; } success = lightingShader.link(); if(!success) { qDebug() << "shaderProgram link failed!" << lightingShader.log(); } success = lampShader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/lamp.vert"); if (!success) { qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lampShader.log(); return success; } success = lampShader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/lamp.frag"); if (!success) { qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lampShader.log(); return success; } success = lampShader.link(); if(!success) { qDebug() << "shaderProgram link failed!" << lampShader.log(); } return success; } void LightWidget::keyPressEvent(QKeyEvent *event) { int key = event->key(); if (key >0 && key < 1024){ m_camera->keys[key] = true; } } void LightWidget::keyReleaseEvent(QKeyEvent *event) { int key = event->key(); if (key >0 && key < 1024){ m_camera->keys[key] = false; } } void LightWidget::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton){ m_bLeftPressed = true; m_lastPos = event->pos(); } } void LightWidget::mouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); m_bLeftPressed = false; } void LightWidget::mouseMoveEvent(QMouseEvent *event) { if(m_bLeftPressed){ int xPos = event->pos().x(); int yPos = event->pos().y(); int xOffset = m_lastPos.x() - xPos; int yOffset = yPos - m_lastPos.y(); m_camera->processMouseMovement(xOffset,yOffset); } } void LightWidget::wheelEvent(QWheelEvent *event) { QPoint offset = event->angleDelta(); m_camera->processMouseScroll(offset.y()/20.0f); }
#ifndef LIGHTWIDGET_H #define LIGHTWIDGET_H #include <QWidget> #include <QOpenGLWidget> #include <QOpenGLShaderProgram> #include <QOpenGLFunctions> #include <QOpenGLVertexArrayObject> #include <QOpenGLBuffer> #include <QOpenGLTexture> #include "ACamera.h" class LightWidget : public QOpenGLWidget,protected QOpenGLFunctions { Q_OBJECT public: LightWidget(QWidget *parent = 0); ~LightWidget() Q_DECL_OVERRIDE; protected: virtual void initializeGL() Q_DECL_OVERRIDE; virtual void resizeGL(int w, int h) Q_DECL_OVERRIDE; virtual void paintGL() Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; private: bool createShader(); private: QOpenGLShaderProgram lightingShader, lampShader; QOpenGLBuffer vbo; QOpenGLVertexArrayObject cubeVAO, lightVAO; QTimer* m_pTimer = nullptr; int m_nTimeValue = 0; // camera ACamera *m_camera; bool m_bLeftPressed; QPoint m_lastPos; }; #endif // LIGHTWIDGET_H
#version 330 core layout (location = 0) in vec3 aPos; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(){ gl_Position = projection * view * model * vec4(aPos, 1.0f); }
#version 330 core out vec4 FragColor; uniform vec3 objectColor; uniform vec3 lightColor; void main() { FragColor = vec4(objectColor * lightColor, 1.0f); }
#version 330 core layout (location = 0) in vec3 aPos; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(){ gl_Position = projection * view * model * vec4(aPos, 1.0f); }
#version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f); }