zoukankan      html  css  js  c++  java
  • 光照--贴图

    https://learnopengl-cn.github.io/02%20Lighting/04%20Lighting%20maps/

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

    #include "widget.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 = new 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();
    
        if (m_pDiffuseMap) {
            delete m_pDiffuseMap;
        }
    
        if (m_pSpecularMap) {
            delete m_pSpecularMap;
        }
    
        doneCurrent();
    }
    
    void QtFunctionWidget::initializeGL(){
        this->initializeOpenGLFunctions();
    
        createShader();
    
        // set up vertex data (and buffer(s)) and configure vertex attributes
        // ------------------------------------------------------------------
        float vertices[] = {
            // positions          // normals           // texture coords
            -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
             0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
             0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
             0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
            -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
    
            -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
             0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
             0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
            -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
    
            -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
            -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
            -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
    
             0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
             0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
             0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
    
            -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
             0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f,
             0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
             0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
            -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f,
            -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
    
            -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
             0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
             0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
             0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
            -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
            -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.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);
    
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
            glEnableVertexAttribArray(1);
            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
            glEnableVertexAttribArray(2);
        }
    
        {
            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, 8 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
        }
    
        // load textures (we now use a utility function to keep the code more organized)
        // -----------------------------------------------------------------------------
        m_pDiffuseMap = loadTexture(":/image/container2.png");
        m_pSpecularMap = loadTexture(":/image/container2_specular.png");
    
        // shader configuration
        // --------------------
        lightingShader.bind();
        lightingShader.setUniformValue("material.diffuse", 0);
        lightingShader.setUniformValue("material.specular", 1);
        lightingShader.release();
    
        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
        lightingShader.setUniformValue("light.ambient", QVector3D(0.2f, 0.2f, 0.2f));
        lightingShader.setUniformValue("light.diffuse", QVector3D(0.5f, 0.5f, 0.5f));
        lightingShader.setUniformValue("light.specular", QVector3D(1.0f, 1.0f, 1.0f));
    
        // material properties
        lightingShader.setUniformValue("material.shininess", 64.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);
    
        // bind diffuse map
        glActiveTexture(GL_TEXTURE0);
        m_pDiffuseMap->bind();
    
        // bind specular map
        glActiveTexture(GL_TEXTURE1);
        m_pSpecularMap->bind();
    
        {// 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, ":/shader/lighting_maps.vert");
        if (!success) {
            qDebug() << "shaderProgram addShaderFromSourceFile failed!" << lightingShader.log();
            return success;
        }
    
        success = lightingShader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/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, ":/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;
    }
    
    QOpenGLTexture *QtFunctionWidget::loadTexture(const QString &path)
    {
        QOpenGLTexture* pTexture = new QOpenGLTexture(QImage(path), QOpenGLTexture::GenerateMipMaps);
        if(!pTexture->isCreated()){
            qDebug() << "Failed to load texture";
        }
        // set the texture wrapping parameters
        pTexture->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        pTexture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        // set texture filtering parameters
        pTexture->setMinificationFilter(QOpenGLTexture::Linear);   //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        pTexture->setMagnificationFilter(QOpenGLTexture::Linear);
    
        return pTexture;
    }
    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();
        QOpenGLTexture* loadTexture(const QString& path);
    
    private:
        QOpenGLShaderProgram lightingShader, lampShader;
        QOpenGLBuffer vbo;
        QOpenGLVertexArrayObject cubeVAO, lightVAO;
        QOpenGLTexture* m_pDiffuseMap = nullptr;
        QOpenGLTexture* m_pSpecularMap = nullptr;
    
        QTimer* m_pTimer = nullptr;
        int     m_nTimeValue = 0;
    
        // camera
        std::unique_ptr<Camera> camera;
        bool m_bLeftPressed;
        QPoint m_lastPos;
    };
    
    #endif // QTFUNCTIONWIDGET_H
    hpp
    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aNormal;
    layout (location = 2) in vec2 aTexCoords;
    
    out vec3 FragPos;
    out vec3 Normal;
    out vec2 TexCoords;
    
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    void main()
    {
        FragPos = vec3(model * vec4(aPos, 1.0));
        Normal = mat3(transpose(inverse(model))) * aNormal;  
        TexCoords = aTexCoords;
        
        gl_Position = projection * view * vec4(FragPos, 1.0);
    }
    vert
    #version 330 core
    out vec4 FragColor;
    
    struct Material {
        sampler2D diffuse;
        sampler2D specular;    
        float shininess;
    }; 
    
    struct Light {
        vec3 position;
    
        vec3 ambient;
        vec3 diffuse;
        vec3 specular;
    };
    
    in vec3 FragPos;  
    in vec3 Normal;  
    in vec2 TexCoords;
      
    uniform vec3 viewPos;
    uniform Material material;
    uniform Light light;
    
    void main()
    {
        // ambient
        vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
          
        // diffuse 
        vec3 norm = normalize(Normal);
        vec3 lightDir = normalize(light.position - FragPos);
        float diff = max(dot(norm, lightDir), 0.0);
        vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;  
        
        // 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 * texture(material.specular, TexCoords).rgb;  
            
        vec3 result = ambient + diffuse + specular;
        FragColor = vec4(result, 1.0);
    } 
    frag
  • 相关阅读:
    从xib初始化的UIView如何继承?
    no implicit conversion of nil into String
    @synchronized(self) 加锁引起的Crash
    iOS手工Crash解析
    iOS线程While-True死循环会发生什么
    2019年新年总结
    218. The Skyline Problem-Hard
    ReplayKit 启动录制按钮 RPSystemBroadcastPickerView 的使用
    S212-搜索+字典树-212. Word Search II-(Hard)
    mybatis批量生成
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/12089895.html
Copyright © 2011-2022 走看看