做网站的服务器配置,电商网站建设好么,门户网站建设公司咨询,anivia wordpress在前几篇文章里面学会了通过opengl实现一个立方体#xff0c;那么这篇我们来学习光照。
风氏光照模型的主要结构由3个分量组成#xff1a;环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子#xff1a;
1 环境光照(Ambient …在前几篇文章里面学会了通过opengl实现一个立方体那么这篇我们来学习光照。
风氏光照模型的主要结构由3个分量组成环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子
1 环境光照(Ambient Lighting)即使在黑暗的情况下世界上通常也仍然有一些光亮月亮、远处的光所以物体几乎永远不会是完全黑暗的。为了模拟这个我们会使用一个环境光照常量它永远会给物体一些颜色。
2 漫反射光照(Diffuse Lighting)模拟光源对物体的方向性影响(Directional Impact)。它是风氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源它就会越亮。
3 镜面光照(Specular Lighting)模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。
我们运行下结果如下 1 我们设置顶点着色器
#version 330 core
//顶点着色器uniform mat4 mvp_matrix;
uniform mat4 model_matrix;layout (location 0) in vec3 a_position; //空间坐标
layout (location 1) in vec3 aColor; //颜色
layout (location 2) in vec2 a_texcoord; //纹理out vec3 FragPos;
out vec2 outtexcoord;
out vec3 outclolor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 Normal;void main()
{gl_Position projection*view* model * vec4(a_position, 1.0);outtexcoord a_texcoord;outclolor aColor;
}在设置片段着色器
#version 330 core
//像素着色器
in vec2 outtexcoord;
in vec3 outclolor;
out vec4 FragColor;
in vec3 FragPos;
in vec3 Normal;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform sampler2D texture;void main()
{//ambient 环境光照float ambientStrength 0.1; //环境因子vec3 ambient ambientStrength * lightColor;//环境因子*光照颜色vec3 result ambient * objectColor;//环境因子*光照位置*物体颜色FragColor vec4(result, 1.0);}
上立方体代码
#include widget.h
#include QOpenGLShaderProgram
#include QOpenGLTexture
#include QMouseEvent
#include QDateTime
#include QtMath
#include ui_widget.h#include QOpenGLShaderProgram
#include QOpenGLTexture
#include QMouseEvent//GLfloat light_ambient[4]{0.5, 0.5, 0.5, 1.0};
//GLfloat light_diffuse[4]{1.0, 1.0, 1.0, 1.0};
//GLfloat light_position[4]{0.0, 0.0, 2.0, 0.0};GLfloat LightAmbient[4] {0.5f, 0.5f, 0.5f, 1.0f}; //环境光参数
GLfloat LightDiffuse[4] {1.0f, 1.0f, 1.0f, 1.0f}; //漫散光参数
GLfloat LightPosition[4] {0.0f, 0.0f, 2.0f, 1.0f}; //光源位置
//模型主动刷新帧率
#define ACTION_FPS 60
#define LIGHT_COLOR QVector3D(1.2f, 1.0f, 2.0f)
#define EYE_CENTER QVector3D(0.0, 0.0, 3.0)
#define LIGHT_POS QVector3D(2.5f, 2.0f, -1.0f)static const char *vertexShaderSource #version 330\nlayout (location 0) in vec4 vertex;\nlayout (location 1) in vec4 texCoord;\nout vec4 texc;\nout vec3 ourColor;\nuniform mat4 model;\nvoid main(void)\n{\n gl_Position model * vertex;\n texc texCoord;\n}\n;static const char *fragmentShaderSource #version 330\nuniform sampler2D texture;\nin vec3 ourColor;\nin vec4 texc;\nvoid main(void)\n{\n gl_FragColor texture2D(texture, texc.st)* vec4(1.0f, 0.5f, 0.5f, 1.0);\n}\n;static const char *vertex1ShaderSource #version 330\nlayout (location 0) in vec4 aPos;\nlayout (location 1) in vec4 aColor;\nuniform mat4 model;\nuniform mat4 view;\nuniform mat4 projection;\nout vec4 FragPos;\nout vec4 Normal;\nvoid main(void)\n{\n// FragPos vec3(model * vec4(aPos, 1.0));\n// Normal mat3(transpose(inverse(model))) * aNormal;\n gl_Position projection * view * model * aPos;\n}\n;
static const char *vertex2ShaderSource #version 330\nlayout (location 0) in vec4 aPos;\nout vec3 result;\nuniform mat4 model;\nuniform mat4 view;\nuniform mat4 projection;\nuniform vec3 objectColor;\nuniform vec3 lightColor;\nuniform float ambientStrength;\nvoid main(void)\n{\n gl_Position projection * view * model * aPos;\n vec3 ambient ambientStrength * lightColor;\n result ( ambient ) * objectColor;\n}\n;
static const char *fragment1ShaderSource #version 330\nin vec3 FragPos;\nin vec3 Normal;\nuniform vec3 lightPos;\nuniform vec3 viewPos;\nuniform vec3 objectColor;\nuniform vec3 lightColor;\nvoid main(void)\n{\n// ambient float ambientStrength 0.1;\n vec3 ambient ambientStrength * lightColor;\n// diffuse vec3 norm normalize(Normal);\n vec3 lightDir normalize(lightPos - FragPos);\n float diff max(dot(norm, lightDir), 0.0);\n vec3 diffuse diff * lightColor; \n// specular float specularStrength 0.5;\n vec3 viewDir normalize(viewPos - FragPos);\n vec3 reflectDir reflect(-lightDir, norm);\n float spec pow(max(dot(viewDir, reflectDir), 0.0), 32);\n vec3 specular specularStrength * spec * lightColor;\n vec3 result (ambient diffuse specular) * objectColor;\n gl_FragColor vec4(result, 1.0);\n}\n;
static const char *vertexLight1Source #version 330\nlayout (location 0) in vec4 aPos;\nlayout (location 1) in vec4 aColor;\nuniform mat4 matrix;\nuniform mat4 view;\nuniform mat4 projection;\nvoid main(void)\n{\n gl_Position projection * view * matrix * aPos;\n}\n;// gl_FragColor texture2D(texture, texc.st) *vec4(1.0f, 0.5f, 0.5f, 1.0);\n
static const char *fragmentLight1Source #version 330\nout vec4 FragColor;\nvoid main(void)\n{\nFragColor vec4(1.0);\n}\n;//static const char *vertexLightSource
// #version 330\n
// layout (location 0) in vec4 aPos;\n
// layout (location 1) in vec4 aTexCord;\n
// uniform mat4 matrix;\n
// uniform mat4 view;\n
// uniform mat4 projection;\n
// out vec4 texc;\n
// void main(void)\n
// {\n
// gl_Position projection * view * matrix * aPos;\n
// texc aTexCord;\n
// }\n; gl_FragColor texture2D(texture, texc.st) *vec4(1.0f, 0.5f, 0.5f, 1.0);\n
//static const char *fragmentLightSource
// #version 330\n
// out vec4 FragColor;\n
// uniform sampler2D texture;\n
// in vec4 texc;\n
// uniform vec3 objectColor;\n
// uniform vec3 lightColor;\n
// void main(void)\n
// {\n
// gl_FragColor vec4(lightColor * objectColor, 1.0);\n
// }\n;Widget::Widget():QOpenGLWidget(),m_xRos(0),m_yRos(0)
{cam QVector3D(m_xRos, m_yRos, m_zRos);cameraPos QVector3D(0, 0, 3);timer new QTimer;timer-setInterval(20);connect(timer,QTimer::timeout,this,[]{qDebug()timeout;// m_xRos30;// m_yRos30;//rotateBy(2 * 16, 2 * 16, -1 * 16);rotateBy(10 * 16, 10 * 16, -1 * 16);});timer-start();
}
Widget::~Widget()
{makeCurrent();vbo.destroy();for (int i 0; i 6; i)delete textures[i];delete program;doneCurrent();
}QSize Widget::minimumSizeHint() const
{return QSize(400, 400);
}QSize Widget::sizeHint() const
{return QSize(400, 400);
}void Widget::rotateBy(int xAngle, int yAngle, int zAngle)
{xRot xAngle;yRot yAngle;zRot zAngle;update();timer-stop();
}void Widget::setClearColor(const QColor color)
{clearColor color;update();
}void Widget::initializeGL()
{/*vertices {// ---- 位置---- - 纹理坐标 - ---- 颜色 ----0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.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, 0.0f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.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, 0.0f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.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, 0.0f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.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, 0.0f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.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, 0.0f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.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, 0.0f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,};*/vertices {// ---- 位置---- - 纹理坐标 - ---- 颜色 ----0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//10.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//20.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//3-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//40.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//5-0.5f, -0.5f, 0.5f,1.0f, 1.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, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,};GLushort indices[36] {/*** 每两个三角形渲染一个面* 注意节点顺序因为开启了遮挡剔除(glEnable(GL_CULL_FACE)),opengl是根据顶点顺序决定三角形法线方向的,顺时针顺序算出来* 三角形是朝里的就不画了,所以 0 3 1 会导致该三角形不显示,后面的三角形同样的道理注意顶点顺序*///Face 00, 1 , 3, //triangle12, 0, 3, //triangle2//Face 14, 5, 7, //triangle36, 4, 7, //triangle4//Face 28, 9, 11, //triangle510, 8, 11, //triangle6//Face 312, 13, 15, //triangle714, 12, 15, //triangle8//Face 416, 17, 19, //triangle918, 16, 19, //triangle10//Face 520, 21, 23, //triangle1122, 20, 23, //triangle12};initializeOpenGLFunctions();// makeObject();//#define PROGRAM_VERTEX_ATTRIBUTE 0//#define PROGRAM_TEXCOORD_ATTRIBUTE 1// lightinhProgram new QOpenGLShaderProgram;
// lightinhProgram-addShaderFromSourceFile(QOpenGLShader::Vertex, :/Diffuse.vs);
// lightinhProgram-addShaderFromSourceFile(QOpenGLShader::Fragment,:/Diffuse.fs);
// lightinhProgram-link();
// lightinhProgram-bind();//激活Program对象program new QOpenGLShaderProgram;program-addShaderFromSourceFile(QOpenGLShader::Vertex, :/shader.vs);program-addShaderFromSourceFile(QOpenGLShader::Fragment,:/shader.fs);program-link();program-bind();//激活Program对象vbo.create();vbo.bind(); //绑定到当前的OpenGL上下文,vbo.allocate(vertices.constData(), vertices.count() * sizeof(GLfloat));//初始化VAO,设置顶点数据状态(顶点法线纹理坐标等)vao.create();vao.bind();// indexBuf.create();
// indexBuf.bind();
// indexBuf.allocate(indices, 36 * sizeof(GLushort));for (int j 0; j 6; j){textures[j] new QOpenGLTexture(QImage(QString(:/cube%1.png).arg(j1)).mirrored());textures[j]-setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,QOpenGLTexture::Linear);textures[j]-setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);textures[j]-setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);}program-setAttributeBuffer(0, GL_FLOAT, 0, 3, 8 * sizeof(float)); //设置aPos顶点属性program-setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(float), 3, 8 * sizeof(float)); //设置aColor顶点颜色program-setAttributeBuffer(2, GL_FLOAT, 6 * sizeof(float), 2, 8 * sizeof(float)); //设置aColor顶点颜色program-enableAttributeArray(0); //使能aPos顶点属性program-enableAttributeArray(1); //使能aColor顶点颜色program-enableAttributeArray(2); //使能aColor顶点颜色program-setUniformValue(texture, 0);// lightinhProgram-setAttributeBuffer(0, GL_FLOAT, 0, 3, 8 * sizeof(float)); //设置aPos顶点属性
// lightinhProgram-enableAttributeArray(0); //使能aPos顶点属性projection.setToIdentity();projection.perspective(45,(float)width()/height(),2.0,45.0);//构建透视矩阵,这个可以是固定写法//projection.perspective(45,(float)width()/height(),0.1,100);//构建透视矩阵,这个可以是固定写法program-setUniformValue(projection, projection);//program1-setUniformValue(projection, projection);//program-setUniformValue(texture, 0);// vao.release();// vbo.release();
}void Widget::paintGL()
{glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //设置清屏颜色// glClearColor(0.1f,0.5f,0.7f,1.0f); //设置清屏颜色glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//开启深度测试glEnable(GL_DEPTH_TEST);//开启遮挡剔除glEnable(GL_CULL_FACE);QMatrix4x4 m;m.translate(0.0f, 0.0f, 0.0f);m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f);m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);m.scale(0.5);QMatrix4x4 modelmatrix;//平移至左下角modelmatrix.translate(0.0f, 0.0f, 0.0f);//鼠标滚动旋转角度modelmatrix.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f);modelmatrix.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);modelmatrix.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);//滚轮缩放modelmatrix.scale(0.5);program-setUniformValue(model, modelmatrix);QMatrix4x4 view;view.lookAt(EYE_CENTER, QVector3D(0, 0, -20), QVector3D(0, 1, 0));program-setUniformValue(view, view);program-setUniformValue(lightColor, QVector3D(1.0f, 1.0f, 1.0f));//灯光颜色program-setUniformValue(objectColor, QVector3D(1.0f, 0.5f, 0.3f));//物体颜色for (int i 0; i 6; i) {textures[i]-bind();glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);}
}
void Widget::resizeGL(int width, int height)
{this-glViewport(0,0,width,height); //定义视口区域
}void Widget::mousePressEvent(QMouseEvent *event)
{lastPos event-pos();
}void Widget::mouseMoveEvent(QMouseEvent *event)
{int dx event-x() - lastPos.x();int dy event-y() - lastPos.y();if (event-buttons() Qt::LeftButton) {rotateBy(8 * dy, 8 * dx, 0);} else if (event-buttons() Qt::RightButton) {rotateBy(8 * dy, 0, 8 * dx);}lastPos event-pos();
}void Widget::mouseReleaseEvent(QMouseEvent * /* event */)
{// emit clicked();
}
#ifndef WIDGET_H
#define WIDGET_H#include QWidget#include QOpenGLWidget
#include QOpenGLExtraFunctions
#include QOpenGLBuffer
#include QOpenGLShaderProgram
#include QOpenGLVertexArrayObject
#include QTimer
#include QOpenGLTexture
#include QOpenGLWidget
#include QOpenGLFunctions
#include QOpenGLBuffer
#include QOpenGLVertexArrayObject
#include QTimernamespace Ui {
class Widget;
}QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram);
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)class Widget : public QOpenGLWidget, protected QOpenGLFunctions
{Q_OBJECTpublic://using QOpenGLWidget::QOpenGLWidget;Widget();~Widget();QSize minimumSizeHint() const override;QSize sizeHint() const override;void rotateBy(int xAngle, int yAngle, int zAngle);void setClearColor(const QColor color);void drawLight();signals:// void clicked();protected:void initializeGL() override;void paintGL() override;void resizeGL(int width, int height) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:Ui::Widget *ui;QColor clearColor Qt::black;QPoint lastPos;int xRot 0;int yRot 0;int zRot 0;QOpenGLTexture *textures[6] {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};QOpenGLShaderProgram *program nullptr;QOpenGLShaderProgram *lightinhProgram nullptr;QOpenGLBuffer vbo;QVectorfloat vertices;QOpenGLVertexArrayObject vao;QOpenGLVertexArrayObject vao1;QTimer* timer;float m_xRos 0.0f;float m_yRos 0.0f;float m_zRos 3.0f;QVector3D cam;int nCount0;QVector3D cameraPos;QVector3D cameraTarget;QVector3D cameraDirection;float m_viewAngle0.0f;float radius 10.0f;float camX 10.0f;float camZ 10.0f;QVector3D _cameraPos {0.0f, 0.0f, 3.0f};QVector3D _cameraFront {0.0f, 0.0f, -1.0f};QVector3D _cameraUp {0.0f, 1.0f, 0.0f};float ambientStrength 0.0;//关照强度QMatrix4x4 projection;QOpenGLTexture *texture;QOpenGLBuffer indexBuf;
};#endif // WIDGET_H运行下结果如下 我们可以看到物体并全黑还是可以看到物体的轮廓为什么变黑呢变黑的原因1.无光源2无 法线。
二 漫反射
环境光照本身不能提供最有趣的结果但是漫反射光照就能开始对物体产生显著的视觉影响了。漫反射光照使物体上与光线方向越接近的片段能从光源处获得更多的亮度。为了能够更好的理解漫反射光照请看下图 图左上方有一个光源它所发出的光线落在物体的一个片段上。我们需要测量这个光线是以什么角度接触到这个片段的。如果光线垂直于物体表面这束光对物体的影响会最大化更亮。为了测量光线和片段的角度我们使用一个叫做法向量(Normal Vector)的东西它是垂直于片段表面的一个向量这里以黄色箭头表示我们在后面再讲这个东西。这两个向量之间的角度很容易就能够通过点乘计算出来。 法向量是一个垂直于顶点表面的单位向量。由于顶点本身并没有表面它只是空间中一个独立的点我们利用它周围的顶点来计算出这个顶点的表面。我们能够使用一个小技巧使用叉乘对立方体所有的顶点计算法向量但是由于3D立方体不是一个复杂的形状所以我们可以简单地把法线数据手工添加到顶点数据中。更新后的顶点数据数组可以在这里找到。试着去想象一下这些法向量真的是垂直于立方体各个平面的表面的一个立方体由6个平面组成。
修改顶点着色器
#version 330 core
layout (location 0) in vec3 aPos;
layout (location 1) in vec3 aNormal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;out vec3 Normal;
out vec3 FragPos;
out vec4 OutTextcord;void main()
{gl_Position projection * view * model * vec4(aPos, 1.0);FragPos vec3(model*vec4(aPos,1.0));Normal mat3(transpose(inverse(model))) * aNormal;}修改片段着色器
#version 330 coreout vec4 FragColor;in vec3 Normal;
in vec3 FragPos;
in vec4 OutTextcord;uniform vec3 viewPos;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform sampler2D texture;void main()
{float ambientStrength 0.1;vec3 ambient ambientStrength * lightColor;// diffusevec3 norm normalize(Normal);vec3 lightDir normalize(lightPos - FragPos);float diff max(dot(norm, lightDir), 0.0);vec3 diffuse diff * lightColor;// specularfloat specularStrength 0.5;vec3 viewDir normalize(viewPos - FragPos);vec3 reflectDir reflect(-lightDir, norm);float spec pow(max(dot(viewDir, reflectDir), 0.0), 32);vec3 specular specularStrength * spec * lightColor;vec3 result (ambient diffuse specular) * objectColor;FragColor vec4(result, 1.0);}#include testshadewidget.h
#define EYE_CENTER QVector3D(0.0, 0.0, 3.0)testshadeWidget::testshadeWidget():QOpenGLWidget(),m_xRos(0),m_yRos(0),m_zRos(0),lightPos(1.0, 1.0, 0.0),m_verticalAngle(45)
{cam QVector3D(m_xRos, m_yRos, m_zRos);cameraPos QVector3D(0, 0, 3);timer new QTimer;timer-setInterval(100);connect(timer,QTimer::timeout,this,[]{qDebug()timeout;// m_xRos30;// m_yRos30;//rotateBy(2 * 16, 2 * 16, -1 * 16);/*if(nDerection0) //RIGHT{m_xRos 0.05f;m_yRos 0;m_zRos 0;if(m_xRos1.0f){m_xRos 0.0f;timer-stop();}}else if(nDerection1)//LEFT{m_xRos - 0.05f;m_yRos 0;m_zRos 0;if(m_xRos-1.0f){m_xRos 0.0f;timer-stop();}}else if(nDerection2)//DOWN{m_xRos 0;m_yRos - 0.05f;m_zRos 0;if(m_yRos-1.0f){m_yRos 0.0f;timer-stop();}}else if(nDerection3)//UP{m_xRos 0;m_yRos 0.05f;m_zRos 0;if(m_yRos1.0f){m_yRos 0.0f;timer-stop();}}update();// offsetBy(10 * 16, 10 * 16, -1 * 16);*/rotateBy(10 * 16, 10 * 16, -1 * 16);});timer-start();
}testshadeWidget::~testshadeWidget()
{}void testshadeWidget::initializeGL()
{float vertices22[] { // ---- 顶点 ---- - 法向量 -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,//1 正面 -z垂直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,//2上面 垂直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,//3右边 x-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,//4 左边 -x0.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,//5 后面 z-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,//6下面-y};float vertices11[] {// ---- 顶点 ---- - 法向量 -// ---- 顶点 ---- - 法向量 - - 纹理 -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, 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, //1 正面 -z垂直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, 1.0f,0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f,1.0f, //2上面 垂直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, 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, //3右边 x-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, 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, //4 左边 -x0.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, 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, //5 后面 z-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, 1.0f,0.0f,-0.5f, 0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f,1.0f, //6下面-y};vertices {// ---- 位置---- - 纹理坐标 - ---- 颜色 ----0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//10.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//20.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//3-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//40.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//5-0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.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, 0.0f, 0.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,//6};//绑定OpenGL函数指针类似GLAD库的作用initializeOpenGLFunctions();//开启深度测试glEnable(GL_DEPTH_TEST);lightprogram new QOpenGLShaderProgram;lightprogram-addShaderFromSourceFile(QOpenGLShader::Vertex, :/base_lighting.vs);lightprogram-addShaderFromSourceFile(QOpenGLShader::Fragment,:/base_lighting.fs);lightprogram-link();lightprogram-bind();//激活Program对象program new QOpenGLShaderProgram;
// program-addShaderFromSourceFile(QOpenGLShader::Vertex, :/shader.vs);
// program-addShaderFromSourceFile(QOpenGLShader::Fragment,:/shader.fs);program-addShaderFromSourceFile(QOpenGLShader::Vertex, :/Diffuse.vs);program-addShaderFromSourceFile(QOpenGLShader::Fragment,:/Diffuse.fs);program-link();program-bind();//激活Program对象unsigned int indices[] {0, 1, 3, // first triangle1, 2, 3 // second triangle};vbo.create();vbo.bind(); //绑定到当前的OpenGL上下文,vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);vbo.allocate(vertices22, sizeof(vertices22));//vbo.allocate(vertices.constData(), vertices.count() * sizeof(GLfloat));vao.create();vao.bind();// _ebo new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
// _ebo-create();
// if(!_ebo-bind()){
// qDebug() ebo绑定失败;
// }
// _ebo-allocate(indices, sizeof(indices));for (int j 0; j 6; j){textures[j] new QOpenGLTexture(QImage(QString(:/cube%1.png).arg(j1)).mirrored());textures[j]-setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,QOpenGLTexture::Linear);textures[j]-setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);textures[j]-setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);}program-setAttributeBuffer(0, GL_FLOAT, 0, 3, 6 * sizeof(float)); //设置aPos顶点属性program-setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(float), 3, 6 * sizeof(float)); //设置aColor顶点颜色// program-setAttributeBuffer(2, GL_FLOAT, 6 * sizeof(float), 2, 8 * sizeof(float)); //设置aColor顶点颜色program-enableAttributeArray(0); //使能aPos顶点属性program-enableAttributeArray(1); //使能aColor顶点颜色// program-enableAttributeArray(2); //使能aColor顶点颜色//program-setUniformValue(texture, 0);lightVao.create();lightVao.bind();lightprogram-setAttributeBuffer(0, GL_FLOAT, 0, 3, 6 * sizeof(float));lightprogram-enableAttributeArray(0); // 使能 location 0的顶点属性aPos
}
void testshadeWidget::rotateBy(int xAngle, int yAngle, int zAngle)
{xRot xAngle;yRot yAngle;zRot zAngle;update();//timer-stop();
}void testshadeWidget::offsetBy(int xPos, int yPos, int zPos)
{m_xRos xPos;m_yRos yPos;m_zRos zPos;update();
}void testshadeWidget::mouseMoveEvent(QMouseEvent *event)
{
// if(event-x() m_cursorPos.x() m_cursorPos.y() event-y())
// return;// QPoint MovePos QCursor::pos();
// QPoint currentPos mapFromGlobal(MovePos);
// int xoffset 0;
// int yoffset 0;
// xoffset currentPos.x() - m_cursorPos.x();
// yoffset currentPos.y() - m_cursorPos.y();// qDebug()1111111111m_xRos;
// if(xoffset0 )
// {
// m_xRos 0.1;
// m_yRos 0;
// if(m_xRos1.0f)
// {
// m_xRos 0.0f;
// m_yRos 0.0f;
// }
// }
// else if(xoffset0 )
// {
// m_xRos - 0.1;
// m_yRos 0;
// if(m_xRos-1.0f)
// {
// m_xRos 0.0f;
// m_yRos 0.0f;
// }
// }
// else if(yoffset0)
// {
// m_xRos 0;
// m_yRos - 0.1;
// if(m_yRos-1.0f)
// {
// m_xRos 0.0f;
// m_yRos 0.0f;
// }
// }
// else if(yoffset0)
// {
// m_xRos 0;
// m_yRos 0.1;
// if(m_yRos1.0f)
// {
// m_xRos 0.0f;
// m_yRos 0.0f;
// }
// }
// update();
// m_cursorPos currentPos;//timer-start();//m_yRos yPos;//update();//m_yRos yoffset;//qDebug()mouseMoveEventxoffsetyoffsetm_xRosm_yRosxPosyPos;//qDebug()m_cursorPos(m_xRos1.0);//m_cursorPos QPoint(event-x(),event-y());}void testshadeWidget::mouseReleaseEvent(QMouseEvent *event)
{if(event-x() m_cursorPos.x() m_cursorPos.y() event-y())return;QPoint MovePos QCursor::pos();QPoint currentPos mapFromGlobal(MovePos);int xoffset 0;int yoffset 0;xoffset currentPos.x() - m_cursorPos.x();yoffset currentPos.y() - m_cursorPos.y();if( xoffset0 (yoffset-15 yoffset15)){nDerection 0;}else if(xoffset0 (yoffset-15 yoffset15)){nDerection 1;}else if(yoffset0 (xoffset-15 xoffset15))//down{nDerection 2;}else if(yoffset0 (xoffset-15 xoffset15))//up{nDerection 3;}qDebug()1111111111m_xRosnDerectionxoffsetyoffset;timer-start();
}void testshadeWidget::mousePressEvent(QMouseEvent *event)
{if(event-button() Qt::LeftButton){m_cursorGlobalPos QCursor::pos();m_cursorPos mapFromGlobal(m_cursorGlobalPos);}
}void testshadeWidget::paintGL()
{glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //设置清屏颜色glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// //开启深度测试//glEnable(GL_DEPTH_TEST);
// //开启遮挡剔除// glEnable(GL_CULL_FACE);QMatrix4x4 m;m.translate(m_xRos, m_yRos, m_zRos);m.rotate(xRot / 16.0f, 1.0f, 0.0f, 0.0f);m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);m.scale(0.5);program-bind();QMatrix4x4 view;view.lookAt(QVector3D(0,0,3), QVector3D(0,0,3)QVector3D(0,0,-1), QVector3D(0,1,0));QMatrix4x4 projection;projection.perspective(45.0f,float(this-width())/float(this-height()),0.1f,100.0f);program-setUniformValue(model, m);program-setUniformValue(view, view);program-setUniformValue(projection, projection);program-setUniformValue(objectColor, QVector3D(1.0f, 0.5f, 0.3f));//物体颜色program-setUniformValue(lightColor, QVector3D( 1.0f, 1.0f, 1.0f));program-setUniformValue(lightPos, QVector3D(1.2f, 1.0f, 2.0f));//光位置for(int i0;i6;i){glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);}vao.bind(); lightprogram-bind();QMatrix4x4 model;model.translate(0.5f, 0.5f, 0.5f);model.scale(0.2);lightprogram-setUniformValue(view, view);lightprogram-setUniformValue(model, model);lightprogram-setUniformValue(projection, projection);lightVao.bind();//glDrawArrays(GL_TRIANGLES, 0, 36);for(int i0;i6;i){glDrawArrays(GL_TRIANGLE_FAN, i*4, 4);}}void testshadeWidget::resizeGL(int width, int height)
{
// QMatrix4x4 projection;
// projection.perspective(m_verticalAngle, width/height, 0.01, 100);
// // m_verticalAngle: 设置垂直角度(值越大,那么物体越小)
// // width()/height(): 设置宽高比
// // 0.1 100: 设置近远平面距离
// glUseProgram(program-programId());
// program-setUniformValue(projection, projection);this-glViewport(0,0,width,height); //定义视口区域this-update();
}#ifndef TESTSHADEWIDGET_H
#define TESTSHADEWIDGET_H#include QWidget
#include QOpenGLWidget
#include QOpenGLExtraFunctions
#include QOpenGLBuffer
#include QOpenGLShaderProgram
#include QOpenGLVertexArrayObject
#include QTimer
#include QOpenGLTexture
#include QOpenGLWidget
#include QOpenGLFunctions
#include QOpenGLBuffer
#include QOpenGLVertexArrayObject
#include QTimer
#include QMouseEventQT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram);
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
class testshadeWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:testshadeWidget();~testshadeWidget();
protected:void initializeGL() override;void paintGL() override;void resizeGL(int width, int height) override;void rotateBy(int xAngle, int yAngle, int zAngle);void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void offsetBy(int xPos, int yPos, int zPos);
private:QOpenGLTexture *textures[6] {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};QOpenGLShaderProgram *program nullptr;QOpenGLBuffer vbo;QVectorfloat vertices;QOpenGLVertexArrayObject vao;QTimer* timer;float m_xRos 0.0f;float m_yRos 0.0f;float m_zRos 0.0f;QVector3D cameraPos;QVector3D cameraTarget;QVector3D cameraDirection;QOpenGLTexture *texture;QMatrix4x4 projection;QVector3D cam;int xRot 0;int yRot 0;int zRot 0;QPoint m_cursorPos;QPoint m_cursorGlobalPos;int nDerection0;QVector3D lightPos;float m_verticalAngle; // 视角缩放QOpenGLShaderProgram *lightprogram nullptr;QOpenGLVertexArrayObject lightVao;QOpenGLBuffer *_ebo;};#endif // TESTSHADEWIDGET_H我们运行下 这里是不是有阴影和光照了。 我们来解释下方向量的定义。 我们看下正面这个面垂直于这个面的是不是Z轴那就是z轴是1其他是0在看垂直于这个面的是不是Z轴反方向所以是-1所以法向量是0,0,-1。