zoukankan      html  css  js  c++  java
  • 光照--材质

    https://learnopengl-cn.github.io/02%20Lighting/03%20Materials/

    https://www.jianshu.com/p/855ce8d81849

    #include "QtFunctionWidget.h"
    #include <QDebug>
    #include <QTimer>
    
    // lighting
    static QVector3D lightPos(1.2f, 1.0f, 2.0f);
    
    QtFunctionWidget::QtFunctionWidget(QWidget *parent) : QOpenGLWidget (parent),
        vbo(QOpenGLBuffer::VertexBuffer)
    {
        camera = std::make_unique<Camera>(QVector3D(0.0f, 0.0f, 3.0f));
        m_bLeftPressed = false;
    
        m_pTimer = new QTimer(this);
        connect(m_pTimer, &QTimer::timeout, this, [=]{
            m_nTimeValue += 1;
            update();
        });
        m_pTimer->start(40);//25 fps
    }
    
    QtFunctionWidget::~QtFunctionWidget(){
        makeCurrent();
    
        lightVAO.destroy();
        cubeVAO.destroy();
        vbo.destroy();
    
        doneCurrent();
    }
    
    void QtFunctionWidget::initializeGL(){
        this->initializeOpenGLFunctions();
    
        createShader();
    
        // set up vertex data (and buffer(s)) and configure vertex attributes
        // ------------------------------------------------------------------
        float vertices[] = {
            -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
            0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
            0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
            0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
            -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
    
            -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
            0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
            -0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
    
            -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
            -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
            -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
            -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
            -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
            -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
    
            0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
            0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
            0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
            0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
            0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
            0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
    
            -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
            0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
            0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
            0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
    
            -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
            0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
            0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
            -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
            -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
        };
    
        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) * 6);
    //        lightingShader.enableAttributeArray(attr);
    //        attr = lightingShader.attributeLocation("aNormal");
    //        lightingShader.setAttributeBuffer(attr, GL_FLOAT, sizeof(GLfloat) * 3, 3, sizeof(GLfloat) * 6);
    //        lightingShader.enableAttributeArray(attr);
    
            // position attribute
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
            // normal attribute
            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
            glEnableVertexAttribArray(1);
        }
    
        {
            QOpenGLVertexArrayObject::Binder vaoBind(&lightVAO);
    
    ////        position attribute
    //        int attr = -1;
    //        attr = lightingShader.attributeLocation("aPos");
    //        lightingShader.setAttributeBuffer(attr, GL_FLOAT, 0, 3, sizeof(GLfloat) * 6);
    //        lightingShader.enableAttributeArray(attr);
    
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
        }
    
    
        vbo.release();
    
        // configure global opengl state
        // -----------------------------
        glEnable(GL_DEPTH_TEST);
    }
    
    void QtFunctionWidget::resizeGL(int w, int h){
        glViewport(0, 0, w, h);
    }
    
    void QtFunctionWidget::paintGL(){
        // input
        // -----
        camera->processInput(0.5f);//speed
    
        // render
        // ------
        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("light.position", lightPos);
        lightingShader.setUniformValue("viewPos", camera->position);
    
        // light properties
        QVector3D lightColor;
        lightColor.setX(sin(m_nTimeValue * /*2.0f*/0.1f));
        lightColor.setY(sin(m_nTimeValue * /*0.7f*/0.035f));
        lightColor.setZ(sin(m_nTimeValue * /*1.3f*/0.065f));
        QVector3D diffuseColor = lightColor   * 0.5f; // decrease the influence
        QVector3D ambientColor = diffuseColor * 0.2f; // low influence
        lightingShader.setUniformValue("light.ambient", ambientColor);
        lightingShader.setUniformValue("light.diffuse", diffuseColor);
        lightingShader.setUniformValue("light.specular", 1.0f, 1.0f, 1.0f);
    
        // material properties
        lightingShader.setUniformValue("material.ambient", QVector3D(1.0f, 0.5f, 0.31f));
        lightingShader.setUniformValue("material.diffuse", QVector3D(1.0f, 0.5f, 0.31f));
        lightingShader.setUniformValue("material.specular", QVector3D(0.5f, 0.5f, 0.5f)); // specular lighting doesn't have full effect on this object's material
        lightingShader.setUniformValue("material.shininess", 32.0f);
    
        // view/projection transformations
        QMatrix4x4 projection;
        projection.perspective(camera->zoom, 1.0f * width() / height(), 0.1f, 100.0f);
        QMatrix4x4 view = 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();
    }
    
    void QtFunctionWidget::keyPressEvent(QKeyEvent *event)
    {
        int key = event->key();
        if (key >= 0 && key < 1024)
            camera->keys[key] = true;
    }
    
    void QtFunctionWidget::keyReleaseEvent(QKeyEvent *event)
    {
        int key = event->key();
        if (key >= 0 && key < 1024)
            camera->keys[key] = false;
    }
    
    void QtFunctionWidget::mousePressEvent(QMouseEvent *event)
    {
        if(event->button() == Qt::LeftButton){
            m_bLeftPressed = true;
            m_lastPos = event->pos();
        }
    }
    
    void QtFunctionWidget::mouseReleaseEvent(QMouseEvent *event)
    {
        Q_UNUSED(event);
    
        m_bLeftPressed = false;
    }
    
    void QtFunctionWidget::mouseMoveEvent(QMouseEvent *event)
    {
        if (m_bLeftPressed) {
            int xpos = event->pos().x();
            int ypos = event->pos().y();
    
            int xoffset = xpos - m_lastPos.x();
            int yoffset = m_lastPos.y() - ypos;
            m_lastPos = event->pos();
            camera->processMouseMovement(xoffset, yoffset);
        }
    }
    
    void QtFunctionWidget::wheelEvent(QWheelEvent *event)
    {
        QPoint offset = event->angleDelta();
        camera->processMouseScroll(offset.y()/20.0f);
    }
    
    bool QtFunctionWidget::createShader()
    {
        bool success = lightingShader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/lighting_maps.vert");
        if (!success) {
            qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lightingShader.log();
            return success;
        }
    
        success = lightingShader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/lighting_maps.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, ":/lamp.vert");
        if (!success) {
            qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lampShader.log();
            return success;
        }
    
        success = lampShader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/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;
    }
    .cpp
    #ifndef QTFUNCTIONWIDGET_H
    #define QTFUNCTIONWIDGET_H
    
    #include <QOpenGLWidget>
    #include <QOpenGLShaderProgram>
    #include <QOpenGLFunctions>
    #include <QOpenGLVertexArrayObject>
    #include <QOpenGLBuffer>
    #include <QOpenGLTexture>
    
    #include "Camera.h"
    
    class QtFunctionWidget : public QOpenGLWidget, protected QOpenGLFunctions
    {
    public:
        QtFunctionWidget(QWidget *parent = nullptr);
        ~QtFunctionWidget() 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
        std::unique_ptr<Camera> camera;
        bool m_bLeftPressed;
        QPoint m_lastPos;
    };
    
    #endif // QTFUNCTIONWIDGET_H
    .hpp

    camera

    #include "Camera.h"
    #include <QDebug>
    
    Camera::Camera(QVector3D position, QVector3D up, float yaw, float pitch) :
        position(position),
        worldUp(up),
        front(-position),
        picth(pitch),
        yaw(yaw),
        movementSpeed(SPEED),
        mouseSensitivity(SENSITIVITY),
        zoom(ZOOM) {
        this->updateCameraVectors();
    
        for(uint i = 0; i != 1024; ++i)
            keys[i] = false;
    }
    
    Camera::~Camera()
    {
    
    }
    
    // Returns the view matrix calculated using Euler Angles and the LookAt Matrix
    QMatrix4x4 Camera::getViewMatrix()
    {
        QMatrix4x4 view;
        view.lookAt(this->position, this->position + this->front, this->up);
        return view;
    }
    
    // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
    void Camera::processKeyboard(Camera_Movement direction, float deltaTime)
    {
        float 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;
    }
    
    // Processes input received from a mouse input system. Expects the offset value in both the x and y direction.
    void Camera::processMouseMovement(float xoffset, float yoffset, bool 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();
    }
    
    // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
    void Camera::processMouseScroll(float 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 Camera::processInput(float 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 Camera::updateCameraVectors()
    {
        // Calculate the new Front vector
        QVector3D front;
        front.setX(cos(this->yaw) * cos(this->picth));
        front.setY(sin(this->picth));
        front.setZ(sin(this->yaw) * cos(this->picth));
        this->front = front.normalized();
        this->right = QVector3D::crossProduct(this->front, this->worldUp).normalized();
        this->up = QVector3D::crossProduct(this->right, this->front).normalized();
    }
    .cpp
    #ifndef CAMERA_H
    #define CAMERA_H
    
    #include <QVector3D>
    #include <QMatrix4x4>
    #include <QKeyEvent>
    
    // Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
    enum Camera_Movement {
      FORWARD,
      BACKWARD,
      LEFT,
      RIGHT,
      UP,
      DOWN
    };
    
    // Default camera values
    const float YAW = -90.0f;
    const float PITCH = 0.0f;
    const float SPEED = 1.0f;
    const float SENSITIVITY = 0.01f;
    const float ZOOM = 45.0f;
    
    class Camera {
    public:
        Camera(QVector3D position = QVector3D(0.0f, 0.0f, 0.0f), QVector3D up = QVector3D(0.0f, 1.0f, 0.0f),
        float yaw = YAW, float pitch = PITCH);
        ~Camera();
    
        QMatrix4x4 getViewMatrix();
        void processMouseMovement(float xoffset, float yoffset, bool constraintPitch = true);
        void processMouseScroll(float yoffset);
        void processInput(float dt);
    
        QVector3D position;
        QVector3D worldUp;
        QVector3D front;
    
        QVector3D up;
        QVector3D right;
    
        //Eular Angles
        float picth;
        float yaw;
    
        //Camera options
        float movementSpeed;
        float mouseSensitivity;
        float zoom;
    
        //Keyboard multi-touch
        bool keys[1024];
    private:
        void updateCameraVectors();
        void processKeyboard(Camera_Movement direction, float deltaTime);
    };
    
    #endif // CAMERA_H
    .hpp

    light

    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aNormal;
    
    out vec3 FragPos;
    out vec3 Normal;
    
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    void main()
    {
        FragPos = vec3(model * vec4(aPos, 1.0));
        Normal = mat3(transpose(inverse(model))) * aNormal;  
        
        gl_Position = projection * view * vec4(FragPos, 1.0);
    }
    .vert
    #version 330 core
    out vec4 FragColor;
    
    struct Material {
        vec3 ambient;
        vec3 diffuse;
        vec3 specular;    
        float shininess;
    }; 
    
    struct Light {
        vec3 position;
    
        vec3 ambient;
        vec3 diffuse;
        vec3 specular;
    };
    
    in vec3 FragPos;  
    in vec3 Normal;  
      
    uniform vec3 viewPos;
    uniform Material material;
    uniform Light light;
    
    void main()
    {
        // ambient
        vec3 ambient = light.ambient * material.ambient;
          
        // diffuse 
        vec3 norm = normalize(Normal);
        vec3 lightDir = normalize(light.position - FragPos);
        float diff = max(dot(norm, lightDir), 0.0);
        vec3 diffuse = light.diffuse * (diff * material.diffuse);
        
        // specular
        vec3 viewDir = normalize(viewPos - FragPos);
        vec3 reflectDir = reflect(-lightDir, norm);  
        float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
        vec3 specular = light.specular * (spec * material.specular);  
            
        vec3 result = ambient + diffuse + specular;
        FragColor = vec4(result, 1.0);
    } 
    .frag

    lamp

    #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);
    }
    .vert
    #version 330 core
    out vec4 FragColor;
     
    void main()
    {
      FragColor = vec4(1.0f);
    }
    .frag
  • 相关阅读:
    Yii2 国际化的问题 zh-CN
    Yii2归档安装法
    MySQL性能优化的最佳20+条经验
    Jquery 选择器汇总
    关于MooTools你应该熟知的6个基本知识
    Android开发效率—Eclipse快捷键
    Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-2.xml, reason: Connectio (andriod sdk manager) http://dl-ssl.google.com/android上不去解决方案
    Windows下搭建objective C开发环境
    android studio创建项目
    android studio 安装与环境搭建
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/12089658.html
Copyright © 2011-2022 走看看