Bläddra i källkod

feat: 添加基本光照计算的测试模块和着色器

NiceTry12138 10 månader sedan
förälder
incheckning
00ca2e0d91

BIN
图形学/OpenGL学习/Image/034.png


+ 92 - 1
图形学/OpenGL学习/OpenGLDemo.md

@@ -556,6 +556,97 @@ glm::vec3 finalColor = lightColor * toyColor;
 
 ![](Image/033.png)
 
-[101中关于漫反射的计算](../Games101/图形学.md#blinn-phong反射模型)
+[101中关于反射的计算](../Games101/图形学.md#blinn-phong反射模型)
+
+根据漫反射、镜面反射和环境光的计算,得到着色器内容如下
+
+- 顶点着色器
+
+通过 `GL_ARRAY_BUFFER` 获得顶点坐标和法线,通过 `uniform` 设置 MVP 矩阵,计算得到顶点的直接坐标 `FragPos`
+
+```cpp
+#version 330 core
+
+layout(location = 0) in vec3 inPosition;
+layout(location = 1) in vec3 inNormal;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+out vec3 Normal;
+out vec3 FragPos;
+
+void main() {
+	gl_Position = projection * view * model * vec4(inPosition, 1.0);
+
+	Normal = inNormal;
+	FragPos = vec3(model * vec4(inPosition, 1.0));
+}
+```
+
+- 片段着色器
+
+通过 `uniform` 设置相机坐标和灯光坐标、灯光颜色、物体颜色等参数
+
+通过顶点着色器得到顶点的世界坐标、顶点法线
+
+```cpp
+#version 330 core
+
+layout(location = 0) out vec4 o_color;
+
+in vec3 FragPos;                // 顶点坐标
+in vec3 Normal;					// 法线向量
+
+uniform vec3 viewPos;           // 相机坐标
+uniform vec3 lightPos;          // 灯的坐标
+
+uniform vec3 objectColor;       // 基本颜色
+uniform vec3 lightColor;        // 灯光颜色
+
+uniform float ambientStrength;  // 环境光强度
+uniform float diffuseStrength;  // 漫反射强度
+uniform float specularStrength;	// 镜面反射强度
+
+void main() {
+	// 环境光
+	vec3 ambient = ambientStrength * lightColor;
+	
+	vec3 normal = normalize(Normal);
+	vec3 lightDir = normalize(lightPos - FragPos);
+
+	// 光的强度与距离有一定关系
+	float lightDis = distance(lightPos, FragPos);
+	float disRate = 1 / lightDis / lightDis;
+
+	// 漫反射
+	float rate = max(dot(lightDir, normal), 0.0);	// 因为光线可能从物体的反面,此时忽略这个,所以用 max(0.0, )
+	vec3 diffuse = disRate * diffuseStrength * rate * lightColor;
+
+	// 镜面反射
+	vec3 enterViewDir = viewPos - FragPos;
+	vec3 halfV = (lightDir + enterViewDir) / length(lightDir + enterViewDir);
+	halfV = normalize(halfV);						// 半程向量
+	float specularRate = pow(max(dot(halfV, normal), 0.0), 32);
+	vec3 specular = disRate * specularStrength * specularRate * lightColor;
+
+	vec3 result = (ambient + diffuse + specular) * objectColor;
+	o_color = vec4(result, 1.0);
+}
+```
+
+跟之前不同的是,这里修改了 `Vertex` 的结构体
+
+```cpp
+// 顶点信息 v1 版本 
+struct Vertex_v1
+{
+	float position[3];			  // 顶点坐标
+	float normal[3];			  // 法线贴图
+};
+```
+
+![](Image/034.png)
 
 

+ 4 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/OpenGLDemo.vcxproj

@@ -466,6 +466,10 @@
     <ClInclude Include="src\Util\UtilTemplate.h" />
   </ItemGroup>
   <ItemGroup>
+    <None Include="res\shader\Light\Fragment.frag" />
+    <None Include="res\shader\Light\LightFragment.frag" />
+    <None Include="res\shader\Light\LightVertex.vert" />
+    <None Include="res\shader\Light\Vertex.vert" />
     <None Include="res\shader\TextPosition\Fragment.frag" />
     <None Include="res\shader\TextPosition\Vertex.vert" />
     <None Include="src\third\glm\detail\func_common.inl" />

+ 4 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/OpenGLDemo.vcxproj.filters

@@ -1416,6 +1416,10 @@
     <None Include="src\third\glm\gtx\wrap.inl">
       <Filter>头文件</Filter>
     </None>
+    <None Include="res\shader\Light\Fragment.frag" />
+    <None Include="res\shader\Light\Vertex.vert" />
+    <None Include="res\shader\Light\LightFragment.frag" />
+    <None Include="res\shader\Light\LightVertex.vert" />
   </ItemGroup>
   <ItemGroup>
     <Image Include="res\textures\test.jpg">

+ 8 - 3
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/imgui.ini

@@ -9,17 +9,22 @@ Size=339,117
 Collapsed=0
 
 [Window][Common Test Title]
-Pos=5,5
+Pos=6,5
 Size=174,184
 Collapsed=0
 
 [Window][ClearColor]
-Pos=330,30
+Pos=398,29
 Size=339,117
 Collapsed=0
 
 [Window][Rotate]
-Pos=422,11
+Pos=438,0
 Size=351,197
 Collapsed=0
 
+[Window][Light]
+Pos=453,20
+Size=339,140
+Collapsed=0
+

+ 41 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/Light/Fragment.frag

@@ -0,0 +1,41 @@
+#version 330 core
+
+layout(location = 0) out vec4 o_color;
+
+in vec3 FragPos;                // 顶点坐标
+in vec3 Normal;					// 法线向量
+
+uniform vec3 viewPos;           // 相机坐标
+uniform vec3 lightPos;          // 灯的坐标
+
+uniform vec3 objectColor;       // 基本颜色
+uniform vec3 lightColor;        // 灯光颜色
+
+uniform float ambientStrength;  // 环境光强度
+uniform float diffuseStrength;  // 漫反射强度
+uniform float specularStrength;	// 镜面反射强度
+
+void main() {
+	// 环境光
+	vec3 ambient = ambientStrength * lightColor;
+	
+	vec3 normal = normalize(Normal);
+	vec3 lightDir = normalize(lightPos - FragPos);
+
+	float lightDis = distance(lightPos, FragPos);
+	float disRate = 1 / lightDis / lightDis;
+
+	// 漫反射
+	float rate = max(dot(lightDir, normal), 0.0);	// 因为光线可能从物体的反面,此时忽略这个,所以用 max(0.0, )
+	vec3 diffuse = disRate * diffuseStrength * rate * lightColor;
+
+	// 镜面反射
+	vec3 enterViewDir = viewPos - FragPos;
+	vec3 halfV = (lightDir + enterViewDir) / length(lightDir + enterViewDir);
+	halfV = normalize(halfV);						// 半程向量
+	float specularRate = pow(max(dot(halfV, normal), 0.0), 32);
+	vec3 specular = disRate * specularStrength * specularRate * lightColor;
+
+	vec3 result = (ambient + diffuse + specular) * objectColor;
+	o_color = vec4(result, 1.0);
+}

+ 9 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/Light/LightFragment.frag

@@ -0,0 +1,9 @@
+#version 330 core
+
+layout(location = 0) out vec4 o_color;
+
+uniform vec4 baseColor;
+
+void main() {
+    o_color = vec4(1.0f, 1.0f, 1.0f, 1.0f); // 混合纹理和颜色
+}

+ 11 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/Light/LightVertex.vert

@@ -0,0 +1,11 @@
+#version 330 core
+
+layout(location = 0) in vec3 inPosition;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main() {
+	gl_Position = projection * view * model * vec4(inPosition, 1.0);
+}

+ 18 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/Light/Vertex.vert

@@ -0,0 +1,18 @@
+#version 330 core
+
+layout(location = 0) in vec3 inPosition;
+layout(location = 1) in vec3 inNormal;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+out vec3 Normal;
+out vec3 FragPos;
+
+void main() {
+	gl_Position = projection * view * model * vec4(inPosition, 1.0);
+
+	Normal = inNormal;
+	FragPos = vec3(model * vec4(inPosition, 1.0));
+}

+ 1 - 1
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/TextPosition/Fragment.frag

@@ -14,5 +14,5 @@ void main() {
         texture(u_Texture0, v_TexCoord) : 
         texture(u_Texture1, v_TexCoord);
     
-    o_color = mix(texColor, v_Color, 0.3); // »ěşĎÎĆŔíşÍŃŐÉ«
+    o_color = mix(texColor, v_Color, 0.3); // 混�纹�和颜色
 }

+ 10 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Camera.cpp

@@ -74,3 +74,13 @@ void Camera::SetRotateSpeed(float rotateSpeed)
 {
 	m_RorateSpeed = rotateSpeed;
 }
+
+void Camera::SetLocation(glm::vec3 inLocation)
+{
+	m_CameraLocation = inLocation;
+}
+
+glm::vec3 Camera::GetCameraLocation()
+{
+	return m_CameraLocation;
+}

+ 3 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Camera.h

@@ -12,6 +12,9 @@ public:
 	void SetFirstMouse(bool bIsFirst);
 	void SetMoveSpeed(float moveSpeed);
 	void SetRotateSpeed(float rotateSpeed);
+	void SetLocation(glm::vec3 inLocation);
+
+	glm::vec3 GetCameraLocation();
 
 private:
 	glm::vec3 m_CameraLocation = glm::vec3(0.0f, 0.0f, 3.0f);

+ 13 - 5
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/CommonData.h

@@ -1,11 +1,19 @@
 #pragma once
 
-// 顶点信息 v0 版本 后续根据需要可能新增 v1、v2 ...
+// 椤剁偣淇℃伅 v0 鐗堟湰 鍚庣画鏍规嵁闇€瑕佸彲鑳芥柊澧� v1銆乿2 ...
 struct Vertex_v0
 {
-	float position[3];			  // 顶点坐标
-	float color[4];				  // 顶点颜色
-	float texCoord[2];			  // 顶点的 UV 坐标	
-	int texIndex;				  // 顶点使用贴图的序号
+	float position[3];			  // 椤剁偣鍧愭爣
+	float color[4];				  // 椤剁偣棰滆壊
+	float texCoord[2];			  // 椤剁偣鐨� UV 鍧愭爣	
+	int texIndex;				  // 椤剁偣浣跨敤璐村浘鐨勫簭鍙�
+};
+
+
+// 椤剁偣淇℃伅 v1 鐗堟湰 
+struct Vertex_v1
+{
+	float position[3];			  // 椤剁偣鍧愭爣
+	float normal[3];			  // 娉曠嚎璐村浘
 };
 

+ 31 - 9
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Shader.cpp

@@ -120,7 +120,7 @@ Shader::~Shader()
 
 void Shader::SetUniform1i(const std::string& inName, const int& value)
 {
-	// 防止使用时忘记先绑定 又为了避免每次设置都绑定 使用 s_CurrentBindShader 记录绑定状态
+	// 闃叉�浣跨敤鏃跺繕璁板厛缁戝畾 鍙堜负浜嗛伩鍏嶆瘡娆¤�缃�兘缁戝畾 浣跨敤 s_CurrentBindShader 璁板綍缁戝畾鐘舵€�
 	Bind();
 	auto location = GetShaderLocation(inName);
 	if (location == -1)
@@ -130,6 +130,17 @@ void Shader::SetUniform1i(const std::string& inName, const int& value)
 	GL_CALL(glUniform1i(location, value));
 }
 
+void Shader::SetUniform1f(const std::string& inName, const float& value)
+{
+	Bind();
+	GLint location = GetShaderLocation(inName);
+	if (location == -1)
+	{
+		return;
+	}
+	GL_CALL(glUniform1f(location, value));
+}
+
 void Shader::SetUniform4f(const std::string& inName, float v0, float v1, float v2, float v3)
 {
 	Bind();
@@ -152,6 +163,17 @@ void Shader::SetUniformMat4f(const std::string& inName, const glm::mat4& inMat4)
 	GL_CALL(glUniformMatrix4fv(location, 1, GL_FALSE, &inMat4[0][0]));
 }
 
+void Shader::SetUniform3f(const std::string& inName, float v0, float v1, float v2)
+{
+	Bind();
+	GLint location = GetShaderLocation(inName);
+	if (location == -1)
+	{
+		return;
+	}
+	GL_CALL(glUniform3f(location, v0, v1, v2));
+}
+
 void Shader::Bind()
 {
 	if (s_CurrentBindShader == m_ShaderID)
@@ -195,7 +217,7 @@ GLint Shader::GetShaderLocation(const std::string& inName)
 		std::cout << "can't find Shader Location with Name " << inName << std::endl;
 	}
 	
-	// shader 内容不会变,同一个 shader 没有这个 name 的槽就一定没有
+	// shader 鍐呭�涓嶄細鍙橈紝鍚屼竴涓� shader 娌℃湁杩欎釜 name 鐨勬Ы灏变竴瀹氭病鏈�
 	m_locationMap[inName] = result;
 
 	return result;
@@ -208,13 +230,13 @@ GLuint Shader::CreateShader(const std::string& vertexSource, const std::string&
 	GLuint vs = CompileShader(vertexSource, GL_VERTEX_SHADER);
 	GLuint fs = CompileShader(fragmentSource, GL_FRAGMENT_SHADER);
 
-	GL_CALL(glAttachShader(program, vs));			// 将 vs 绑定到 program 上
-	GL_CALL(glAttachShader(program, fs));			// 将 fs 绑定到 program 上
+	GL_CALL(glAttachShader(program, vs));			// 灏� vs 缁戝畾鍒� program 涓�
+	GL_CALL(glAttachShader(program, fs));			// 灏� fs 缁戝畾鍒� program 涓�
 
-	GL_CALL(glLinkProgram(program));					// 链接程序,将所有着色器合并为一个可执行的程序
-	GL_CALL(glValidateProgram(program));				// 验证程序是否可以执行
+	GL_CALL(glLinkProgram(program));					// 閾炬帴绋嬪簭锛屽皢鎵€鏈夌潃鑹插櫒鍚堝苟涓轰竴涓�彲鎵ц�鐨勭▼搴�
+	GL_CALL(glValidateProgram(program));				// 楠岃瘉绋嬪簭鏄�惁鍙�互鎵ц�
 
-	GL_CALL(glDeleteShader(vs));						// 删除着色器对象,一旦链接成功那么代码已经连接到程序中了,可以删除着色器对象
+	GL_CALL(glDeleteShader(vs));						// 鍒犻櫎鐫€鑹插櫒瀵硅薄锛屼竴鏃﹂摼鎺ユ垚鍔熼偅涔堜唬鐮佸凡缁忚繛鎺ュ埌绋嬪簭涓�簡锛屽彲浠ュ垹闄ょ潃鑹插櫒瀵硅薄
 	GL_CALL(glDeleteShader(fs));
 	
 	return program;
@@ -225,14 +247,14 @@ GLuint Shader::CompileShader(const std::string& inSource, GLenum inType)
 	GLuint shaderId = glCreateShader(inType);
 
 	const char* source = inSource.c_str();
-	GL_CALL(glShaderSource(shaderId, 1, &source, nullptr));			// 传入 nullptr 表示读取整个字符串数组
+	GL_CALL(glShaderSource(shaderId, 1, &source, nullptr));			// 浼犲叆 nullptr 琛ㄧず璇诲彇鏁翠釜瀛楃�涓叉暟缁�
 	GL_CALL(glCompileShader(shaderId));
 
 	GLint errorId;
 	GL_CALL(glGetShaderiv(shaderId, GL_COMPILE_STATUS, &errorId));
 	if (errorId == GL_FALSE)
 	{
-		// 编译错误
+		// 缂栬瘧閿欒�
 		GLint length = 0;
 		GL_CALL(glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length));
 		

+ 3 - 1
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Shader.h

@@ -9,8 +9,10 @@ public:
 	~Shader();
 
 	void SetUniform1i(const std::string& inName, const int& value);
+	void SetUniform1f(const std::string& inName, const float& value);
 	void SetUniform4f(const std::string& inName, float v0, float v1, float v2, float v3);
 	void SetUniformMat4f(const std::string& inName, const glm::mat4& inMat4);
+	void SetUniform3f(const std::string& inName, float v0, float v1, float v2);
 
 	void Bind();
 	void UnBind();
@@ -29,7 +31,7 @@ private:
 
 	//GLuint CreateShaderWithFile(const std::string& vertexFile, const std::string& fragmentFile);
 private:
-	std::unordered_map<std::string, GLint> m_locationMap;	// ²ÛλӳÉä
+	std::unordered_map<std::string, GLint> m_locationMap;	// 槽�映射
 	GLuint m_ShaderID{ GL_ZERO };
 };
 

+ 97 - 46
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestLight.cpp

@@ -5,25 +5,49 @@ TestLight TestLight::_self;
 
 void TestLight::OnEnter(GLFWwindow* window)
 {
-	//					 坐标					颜色						UV 坐标			贴图序号
-	m_vertexs.push_back({ 0.5f,  0.5f, -0.5f,	1.0f, 1.0f, 0.0f, 1.0f,		1.0f, 1.0f,		0 });
-	m_vertexs.push_back({ 0.5f, -0.5f, -0.5f,	1.0f, 1.0f, 0.0f, 1.0f,		1.0f, 0.0f,		0 });
-	m_vertexs.push_back({ -0.5f, -0.5f, -0.5f,	0.0f, 1.0f, 1.0f, 1.0f,		0.0f, 0.0f,		1 });
-	m_vertexs.push_back({ -0.5f,  0.5f, -0.5f,	0.0f, 1.0f, 1.0f, 1.0f,		0.0f, 1.0f,		1 });
-	m_vertexs.push_back({ 0.5f,  0.5f,  0.5f,	1.0f, 1.0f, 0.0f, 1.0f,		1.0f, 1.0f,		0 });
-	m_vertexs.push_back({ 0.5f, -0.5f,  0.5f,	1.0f, 1.0f, 0.0f, 1.0f,		1.0f, 0.0f,		0 });
-	m_vertexs.push_back({ -0.5f, -0.5f,  0.5f,	0.0f, 1.0f, 1.0f, 1.0f,		0.0f, 0.0f,		1 });
-	m_vertexs.push_back({ -0.5f,  0.5f,  0.5f,	0.0f, 1.0f, 1.0f, 1.0f,		0.0f, 1.0f,		1 });
-
-	GLuint indices[] = {
-		0, 1, 2, 2, 3, 0,			// 组成下面的两个三角形
-		4, 5, 6, 6, 7, 4,			
-		1, 2, 6, 6, 5, 1,
-		0, 1, 5, 5, 4, 0,
-		2, 3, 7, 7, 6, 2,
-		0, 3, 4, 4, 7, 3,
-	};
-	
+	//					 坐标					顶点法线	
+	m_vertexs.push_back({  0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f });
+	m_vertexs.push_back({  0.5f,  0.5f, -0.5f, 0.0f, 0.0f, -1.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f, -0.5f, 0.0f, 0.0f, -1.0f });
+	m_vertexs.push_back({  0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f, -0.5f, 0.0f, 0.0f, -1.0f });
+	m_vertexs.push_back({ -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f });
+
+	m_vertexs.push_back({  0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({  0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({  0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({  0.5f,  0.5f,  0.5f, 1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({  0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({  0.5f, -0.5f,  0.5f, 1.0f, 0.0f, 0.0f });
+
+	m_vertexs.push_back({  0.5f, -0.5f,  0.5f, 0.0f, -1.0f, 0.0f, });
+	m_vertexs.push_back({  0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, });
+	m_vertexs.push_back({ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, });
+	m_vertexs.push_back({ -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, });
+	m_vertexs.push_back({ -0.5f, -0.5f,  0.5f, 0.0f, -1.0f, 0.0f, });
+	m_vertexs.push_back({  0.5f, -0.5f,  0.5f, 0.0f, -1.0f, 0.0f, });
+
+	m_vertexs.push_back({  0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f, });
+	m_vertexs.push_back({  0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, });
+	m_vertexs.push_back({ -0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, });
+	m_vertexs.push_back({ -0.5f,  0.5f, -0.5f, 0.0f, 1.0f, 0.0f, });
+	m_vertexs.push_back({ -0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f, });
+	m_vertexs.push_back({  0.5f,  0.5f,  0.5f, 0.0f, 1.0f, 0.0f, });
+
+	m_vertexs.push_back({  0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f });
+	m_vertexs.push_back({  0.5f,  0.5f,  0.5f, 0.0f, 0.0f, 1.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f,  0.5f, 0.0f, 0.0f, 1.0f });
+	m_vertexs.push_back({  0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f,  0.5f, 0.0f, 0.0f, 1.0f });
+	m_vertexs.push_back({ -0.5f, -0.5f,  0.5f, 0.0f, 0.0f, 1.0f });
+
+	m_vertexs.push_back({ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f, -0.5f, -1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f,  0.5f, -1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({ -0.5f,  0.5f,  0.5f, -1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({ -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f });
+	m_vertexs.push_back({ -0.5f, -0.5f,  0.5f, -1.0f, 0.0f, 0.0f });
+
 	// 启动深度测试
 	glEnable(GL_DEPTH_TEST);
 
@@ -35,41 +59,34 @@ void TestLight::OnEnter(GLFWwindow* window)
 
 	// 创建 VBO IB
 	glGenBuffers(1, &m_VBO);
-	glGenBuffers(1, &m_IB);
 
 	// 绑定 VBO 和 数据
 	GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_VBO));
-	GL_CALL(glBufferData(GL_ARRAY_BUFFER, m_vertexs.size() * sizeof(Vertex_v0), m_vertexs.data(), GL_STATIC_DRAW));
+	GL_CALL(glBufferData(GL_ARRAY_BUFFER, m_vertexs.size() * sizeof(Vertex_v1), m_vertexs.data(), GL_STATIC_DRAW));
 
-	// 绑定 IB 和 数据
-	GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IB));
-	GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
+	// 偷懒 就不用 index buffer 了
+	//GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IB));
+	//GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
 
 	// 设置 VAO 内存结构
 	GL_CALL(glEnableVertexAttribArray(0));
-	GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_v0), (void *)offsetof(Vertex_v0, position)));
+	GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_v1), (void *)offsetof(Vertex_v1, position)));
 
 	GL_CALL(glEnableVertexAttribArray(1));
-	GL_CALL(glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex_v0), (void*)offsetof(Vertex_v0, color)));
-
-	GL_CALL(glEnableVertexAttribArray(2));
-	GL_CALL(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex_v0), (void*)offsetof(Vertex_v0, texCoord)));
-
-	GL_CALL(glEnableVertexAttribArray(3));
-	GL_CALL(glVertexAttribPointer(3, 1, GL_INT, GL_FALSE, sizeof(Vertex_v0), (void*)offsetof(Vertex_v0, texIndex)));
+	GL_CALL(glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex_v1), (void*)offsetof(Vertex_v1, normal)));
 
 	// 初始化 shader
 	//m_Shader.NewInit("res/shader/TextPosition/Vertex.vert", "res/shader/TextPosition/Fragment.frag");
-	m_Shader.Init("res/shader/TextPosition/Vertex.vert", "res/shader/TextPosition/Fragment.frag");
+	m_Shader.Init("res/shader/Light/Vertex.vert", "res/shader/Light/Fragment.frag");
+
+	m_Shader.UnBind();
 
-	// 初始化 texture
-	m_Tex1.Init("res/textures/test2.png");
-	m_Tex2.Init("res/textures/test3.png");
+	m_LightShader.Init("res/shader/Light/LightVertex.vert", "res/shader/Light/LightFragment.frag");
+	m_LightShader.UnBind();
 
-	m_Tex1.Bind(0);
-	m_Tex2.Bind(1);
+	CreateLight();
 
-	m_Shader.UnBind();
+	m_Camera.SetLocation(glm::vec3(0.0f, 0.0f, 3.0f));
 
 	BindMouse(window);
 }
@@ -82,7 +99,6 @@ void TestLight::OnExit(GLFWwindow* window)
 
 void TestLight::UpdateLogic(float delayTime)
 {
-	m_model = glm::mat4(1.0f);
 	m_view = m_Camera.GetView();
 	m_Camera.SetMoveSpeed(m_CameraMoveSpeed);
 	m_Camera.SetRotateSpeed(m_CameraRotateSpeed);
@@ -99,25 +115,46 @@ void TestLight::ClearRender(GLFWwindow* window)
 void TestLight::Render(GLFWwindow* window)
 {
 	m_Shader.Bind();
-	m_Shader.SetUniform1i("u_Texture0", 0);
-	m_Shader.SetUniform1i("u_Texture1", 1);
 
 	m_Shader.SetUniformMat4f("model", m_model);
 	m_Shader.SetUniformMat4f("view", m_view);
 	m_Shader.SetUniformMat4f("projection", m_proj);
 
+	m_Shader.SetUniform3f("objectColor", 1.0f, 0.5f, 0.31f);
+	m_Shader.SetUniform3f("lightColor", 1.0f, 1.0f, 1.0f);
+
+	m_Shader.SetUniform1f("ambientStrength", m_ambientStrength);		// 设置强度
+	m_Shader.SetUniform1f("diffuseStrength", m_diffuseStrength);
+	m_Shader.SetUniform1f("specularStrength",m_specularStrength);
+
+	m_Shader.SetUniform3f("viewPos", m_Camera.GetCameraLocation().x, m_Camera.GetCameraLocation().y, m_Camera.GetCameraLocation().z);
+	m_Shader.SetUniform3f("lightPos", m_LightPos.x, m_LightPos.y, m_LightPos.z);
+
 	glBindVertexArray(m_VAO);
-	glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
+	glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
+
+	auto lightModule = glm::mat4(1.0f);
+	lightModule = glm::translate(lightModule, m_LightPos);
+	lightModule = glm::scale(lightModule, glm::vec3(0.2f)); // a smaller cube
+
+	m_LightShader.Bind();
+	m_LightShader.SetUniformMat4f("model", lightModule);
+	m_LightShader.SetUniformMat4f("view", m_view);
+	m_LightShader.SetUniformMat4f("projection", m_proj);
+
+	glBindVertexArray(m_LightVAO);
+	glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
 }
 
 void TestLight::UpdateImGUI(GLFWwindow* window)
 {
 	const auto& io = ImGui::GetIO();
 
-	ImGui::Begin("Camera");
+	ImGui::Begin("Light");
 
-	ImGui::SliderFloat("Camera Move Speed", &m_CameraMoveSpeed, 0.0f, 0.1f);
-	ImGui::SliderFloat("Camera Rotate Speed", &m_CameraRotateSpeed, 0.01f, 0.1f);
+	ImGui::SliderFloat("Light ambientStrength", &m_ambientStrength, 0.0f, 1.0f);
+	ImGui::SliderFloat("Light diffuseStrength", &m_diffuseStrength, 0.0f, 5.0f);
+	ImGui::SliderFloat("Light specularStrength", &m_specularStrength, 0.0f, 5.0f);
 
 	if (ImGui::Button("Close Window"))
 		glfwSetWindowShouldClose(window, true);
@@ -160,3 +197,17 @@ void TestLight::UnBindMouse(GLFWwindow* window)
 	m_Camera.SetFirstMouse(false);
 	TestWithMouseBase::UnBindMouse(window);
 }
+
+void TestLight::CreateLight()
+{
+	glGenVertexArrays(1, &m_LightVAO);
+	glBindVertexArray(m_LightVAO);
+
+	// 直接沿用立方体数据
+	glBindBuffer(GL_ARRAY_BUFFER, m_VBO);	
+	
+	// 设置 VAO 内存结构 
+	// 灯光只需要位置数据
+	GL_CALL(glEnableVertexAttribArray(0));
+	GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_v1), (void*)offsetof(Vertex_v1, position)));
+}

+ 12 - 6
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestLight.h

@@ -26,30 +26,36 @@ public:
 
 	virtual void BindMouse(GLFWwindow* window) override;
 	virtual void UnBindMouse(GLFWwindow* window) override;
-public:
 
+protected:
+	void CreateLight();
 
 private:
 	GLuint m_VBO{ GL_ZERO };
 	GLuint m_VAO{ GL_ZERO };
-	GLuint m_IB{ GL_ZERO };
 
-	Shader m_Shader;
-	Texture m_Tex1;
-	Texture m_Tex2;
+	GLuint m_LightVAO{ GL_ZERO };
 
-	std::vector<Vertex_v0> m_vertexs;
+	Shader m_Shader;
+	Shader m_LightShader;
+	std::vector<Vertex_v1> m_vertexs;
 
 	glm::mat4 m_model = glm::mat4(1.0f);		// 模型矩阵
 	glm::mat4 m_view = glm::mat4(1.0f);			// 视图矩阵
 	glm::mat4 m_proj = glm::mat4(1.0f);			// 投影矩阵
 
+	glm::vec3 m_LightPos = glm::vec3(1.2f, 1.0f, 2.0f);
+
 	float m_CameraMoveSpeed = 0.1f;
 	float m_CameraRotateSpeed = 0.1f;
 
 	Camera m_Camera;
 	bool m_bLeftAltPress = false;
 
+	float m_ambientStrength = 0.1f;
+	float m_diffuseStrength = 1.0f;
+	float m_specularStrength = 0.5f;
+
 	static TestLight _self;
 };
 

+ 1 - 1
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestModuleManager.cpp

@@ -103,6 +103,6 @@ void TestModuleManager::TestModuleRun(GLFWwindow* window, float deltaTime)
 	TestModule->Update(window, deltaTime);
 
 	TestModule->ClearRender(window);
-	TestModule->RenderImGUI(window);
 	TestModule->Render(window);
+	TestModule->RenderImGUI(window);
 }