欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。
相关背景和学习资料
opengl 着色器原理 https://learnopengl-cn.github.io/01%20Getting%20started/05%20Shaders/
qt opengl 学习视频 https://www.bilibili.com/video/BV1wf4y1E7hY?p=2&vd_source=fb27f95f25902a2cc94d4d8e49f5f777
着色器原理 https://www.bilibili.com/video/BV1X7411F744/?p=7&vd_source=fb27f95f25902a2cc94d4d8e49f5f777
物体光照组成
光照模型
根据blinn-phone 反射模型把光照分成高光部分,漫反射部分和环境光部分
高光部分是有眼睛看向物体表面方向刚好与光反射的方向重合开成的。
漫反射是光打到物体上后向各个方向反射形成的。
环境光部分是物体没有被光照到的部分反射了整个环境光照形成的。
这三个部分可以分别求出,然后相加得到最后的整体效果。
具体表示 可以公式计算得到,也要以由贴图进行渲染。代码实现中是采用后者。
模型组成
assimp插件可以导入模型并将模型分成不同的网格。
每个网格包含以下内容。
点,法向,面,uv坐标等基本几何信息。
高光贴图,漫反射贴图,环境光贴图,凸凹贴图等与渲染相关的信息。
加载与渲染
把一个模型分不同的mesh部分。
每个部分存储几何信息和渲染信息。
绘制时根据几何信息和渲染信息调用着色器进行渲染。
类设计
代码库:https://gitcode.com/chenbb1989/qt-opengl/tree/master/opengl-functionlearn10model
class Model : public QObject,QOpenGLFunctions
{
Q_OBJECT
public:
Model(const QString &path);
void Draw(QOpenGLShaderProgram &shader);
~Model();
private:
QVector<Texture> textures_loaded;
QVector<Mesh*> meshes;// 相信网格
QString directory;
void loadModel(const QString& path); // 加载整体模型
void processNode(aiNode *node,const aiScene *scene);
Mesh* processMesh(aiMesh *mesh, const aiScene *scene); // 存储mesh信息
QVector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type,
QString typeName); // 提取贴图信息
};
class Mesh : public QObject, protected QOpenGLFunctions
{
Q_OBJECT
public:
QVector<Vertex> vertices; // 点
QVector<unsigned int> indices; // 面
QVector<Texture> textures; // 贴图路径
QOpenGLVertexArrayObject VAO;
QOpenGLBuffer EBO;
QOpenGLTexture *texture0=NULL, // 漫反射贴图
*texture1=NULL, // 高光贴图
*texture2=NULL; // 环境光贴图
public:
Mesh(QVector<Vertex> vertices,QVector<unsigned int> indices,QVector<Texture> textures);
Mesh();
void Draw(QOpenGLShaderProgram &shader);
~Mesh();
private:
QOpenGLBuffer VBO;
private:
void setupMesh();
};
效果展示
本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。创作不易,帮忙点击公众号的链接。