gl_NormalMatrix理解和获取

 法线矩阵:G
  模型视图矩阵:M 
   则:        
        G: = M逆矩阵的转置矩阵
        
    若: M是正交矩阵,M的逆矩阵= M的转置矩阵
    所以,当没有Scale变换时,(只存在Rotate、Transform变换)
    ModelView = G 
        

    OSG中计算 gl_NormalMatrix:
    
    if (_normalMatrixUniform.valid())
    {
        Matrix mv(*_modelView);
        mv.setTrans(0.0, 0.0, 0.0); // 法线与平移无关,可以去掉

        Matrix matrix;
        matrix.invert(mv); // 求逆矩阵
        // 进行转置变换
        Matrix3 normalMatrix(matrix(0,0), matrix(1,0), matrix(2,0),
                             matrix(0,1), matrix(1,1), matrix(2,1),
                             matrix(0,2), matrix(1,2), matrix(2,2));

        _normalMatrixUniform->set(normalMatrix);
    }  
  http://www.songho.ca/opengl/gl_normaltransform.html       

 https://www.cnblogs.com/hefee/p/3817397.html        
————————————————
版权声明:本文为CSDN博主「longlongway2012」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kasteluo/article/details/83616914

class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core { public: explicit GLWidget(QWidget* parent = nullptr):QOpenGLWidget(parent),m_program(new QOpenGLShaderProgram(this)) {m_models[0].yTrans = -100.0f;m_models[1].yTrans = 100.0f;} protected: struct Model { std::vector<float> vertices; std::vector<float> normals; GLuint vao = 0; GLuint vbo[2] = {0}; float xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; float xTrans = 0.0f, yTrans = 0.0f; float scale = 0.005f; }; Model m_models[2]; int m_selectedModel = 0; QOpenGLShaderProgram* m_program; QPoint m_lastPos; QMatrix4x4 m_projection; void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.9f, 0.9f, 0.9f, 1.0f); glEnable(GL_DEPTH_TEST); m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/phong.vert"); m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/phong.frag"); m_program->link(); loadModel(m_models[0], ":/models/Fixture.STL", -100.0f); loadModel(m_models[1], ":/models/Light.STL", 100.0f); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_program->bind(); m_program->setUniformValue("projection", m_projection); m_program->setUniformValue("lightPos", QVector3D(0, 0, 500)); m_program->setUniformValue("lightColor", QVector3D(1, 1, 1)); QMatrix4x4 view; view.translate(0, 0, -500); drawBasePlane(view); for (auto& model : m_models) { QMatrix4x4 modelMat; modelMat.translate(model.xTrans, model.yTrans, 0); modelMat.rotate(model.xRot, 1, 0, 0); modelMat.rotate(model.yRot, 0, 1, 0); modelMat.scale(model.scale); m_program->setUniformValue("model", modelMat); m_program->setUniformValue("view", view); m_program->setUniformValue("normalMat", modelMat.normalMatrix()); glBindVertexArray(model.vao); glDrawArrays(GL_TRIANGLES, 0, model.vertices.size()/3); } m_program->release(); } private: void loadModel(Model& model, const QString& path, float yOffset) { Assimp::Importer importer; const aiScene* scene = importer.ReadFile(path.toStdString(),aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_FlipUVs); if (!scene || !scene->mRootNode) {qWarning("Failed to load model: %s", importer.GetErrorString()); return;} for (unsigned i = 0; i < scene->mNumMeshes; ++i) { const aiMesh* mesh = scene->mMeshes[i]; for (unsigned j = 0; j < mesh->mNumFaces; ++j) { const aiFace& face = mesh->mFaces[j]; for (unsigned k = 0; k < 3; ++k) { const aiVector3D& v = mesh->mVertices[face.mIndices[k]]; const aiVector3D& n = mesh->mNormals[face.mIndices[k]]; model.vertices.push_back(v.x); model.vertices.push_back(v.y + yOffset); model.vertices.push_back(v.z); model.normals.push_back(n.x); model.normals.push_back(n.y); model.normals.push_back(n.z); } } } glGenVertexArrays(1, &model.vao); glGenBuffers(2, model.vbo); glBindVertexArray(model.vao); glBindBuffer(GL_ARRAY_BUFFER, model.vbo[0]); glBufferData(GL_ARRAY_BUFFER, model.vertices.size() * sizeof(float),model.vertices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, model.vbo[1]); glBufferData(GL_ARRAY_BUFFER,model.normals.size() * sizeof(float),model.normals.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(1); glBindVertexArray(0); } 分析这段代码,获取模型1的x长度,将其显示在中轴线上,将模型2沿Y方向旋转90度,获取模型2的x长度,将其显示在中轴线上
03-12
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core { public: explicit GLWidget(QWidget* parent = nullptr):QOpenGLWidget(parent),m_program(new QOpenGLShaderProgram(this)) {m_models[0].yTrans = -100.0f;m_models[1].yTrans = 100.0f;} protected: struct Model { std::vector<float> vertices; std::vector<float> normals; GLuint vao = 0; GLuint vbo[2] = {0}; float xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; float xTrans = 0.0f, yTrans = 0.0f; float scale = 0.005f; }; Model m_models[2]; int m_selectedModel = 0; QOpenGLShaderProgram* m_program; QPoint m_lastPos; QMatrix4x4 m_projection; void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.9f, 0.9f, 0.9f, 1.0f); glEnable(GL_DEPTH_TEST); m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, “:/shaders/phong.vert”); m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, “:/shaders/phong.frag”); m_program->link(); loadModel(m_models[0], “:/models/Fixture.STL”, -100.0f); loadModel(m_models[1], “:/models/Light.STL”, 100.0f); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_program->bind(); m_program->setUniformValue(“projection”, m_projection); m_program->setUniformValue(“lightPos”, QVector3D(0, 0, 500)); m_program->setUniformValue(“lightColor”, QVector3D(1, 1, 1)); QMatrix4x4 view; view.translate(0, 0, -500); drawBasePlane(view); for (auto& model : m_models) { QMatrix4x4 modelMat; modelMat.translate(model.xTrans, model.yTrans, 0); modelMat.rotate(model.xRot, 1, 0, 0); modelMat.rotate(model.yRot, 0, 1, 0); modelMat.scale(model.scale); m_program->setUniformValue("model", modelMat); m_program->setUniformValue("view", view); m_program->setUniformValue("normalMat", modelMat.normalMatrix()); glBindVertexArray(model.vao); glDrawArrays(GL_TRIANGLES, 0, model.vertices.size()/3); } m_program->release(); } private: void loadModel(Model& model, const QString& path, float yOffset) { Assimp::Importer importer; const aiScene* scene = importer.ReadFile(path.toStdString(),aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_FlipUVs); if (!scene || !scene->mRootNode) {qWarning(“Failed to load model: %s”, importer.GetErrorString()); return;} for (unsigned i = 0; i < scene->mNumMeshes; ++i) { const aiMesh* mesh = scene->mMeshes[i]; for (unsigned j = 0; j < mesh->mNumFaces; ++j) { const aiFace& face = mesh->mFaces[j]; for (unsigned k = 0; k < 3; ++k) { const aiVector3D& v = mesh->mVertices[face.mIndices[k]]; const aiVector3D& n = mesh->mNormals[face.mIndices[k]]; model.vertices.push_back(v.x); model.vertices.push_back(v.y + yOffset); model.vertices.push_back(v.z); model.normals.push_back(n.x); model.normals.push_back(n.y); model.normals.push_back(n.z); } } } glGenVertexArrays(1, &model.vao); glGenBuffers(2, model.vbo); glBindVertexArray(model.vao); glBindBuffer(GL_ARRAY_BUFFER, model.vbo[0]); glBufferData(GL_ARRAY_BUFFER, model.vertices.size() * sizeof(float),model.vertices.data(), GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, model.vbo[1]); glBufferData(GL_ARRAY_BUFFER,model.normals.size() * sizeof(float),model.normals.data(), GL_STATIC_DRAW); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(1); glBindVertexArray(0); } 分析这段代码,获取模型1的x长度,将其显示在中轴线并且沿Y轴负方向旋转90度,将模型2沿Y方向旋转90度,获取模型2的x长度,将其显示在中轴线上
最新发布
03-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值