Просмотр исходного кода

feat: 添加天空盒的测试和实现,有BUG未修复

NiceTry12138 9 месяцев назад
Родитель
Сommit
4e7bc2f6a5
20 измененных файлов с 460 добавлено и 29 удалено
  1. BIN
      图形学/OpenGL学习/Image/041.png
  2. 14 0
      图形学/OpenGL学习/OpenGLDemo.md
  3. 6 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/OpenGLDemo.vcxproj
  4. 14 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/OpenGLDemo.vcxproj.filters
  5. 7 2
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/imgui.ini
  6. 11 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/SkyBox/skybox.frag
  7. 14 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/SkyBox/skybox.vert
  8. BIN
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/back.jpg
  9. BIN
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/bottom.jpg
  10. BIN
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/front.jpg
  11. BIN
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/left.jpg
  12. BIN
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/right.jpg
  13. BIN
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/top.jpg
  14. 45 26
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/CommonData.h
  15. 118 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/SkyBox.cpp
  16. 32 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/SkyBox.h
  17. 34 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Texture.cpp
  18. 4 1
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Texture.h
  19. 108 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestSkyBox.cpp
  20. 53 0
      图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestSkyBox.h

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


+ 14 - 0
图形学/OpenGL学习/OpenGLDemo.md

@@ -790,4 +790,18 @@ cmake ../ -A win32
 
 ### 帧缓冲
 
+详见 [TestFrameBuffer.cpp](./src/OpenGLDemo/OpenGLDemo/src/testModule/TestFrameBuffer.cpp)
+
+### 立方体贴图
+
+立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面
+
+立方体贴图有一个非常有用的特性,它可以通过一个方向向量来进行索引/采样
+
+![](Image/041.png)
+
+立方体贴图有一个经常使用的场景:**天空盒**
+
+**天空盒** 顾名思义就是其实是将世界包围在一个巨大的盒子里面,然后通过当前相机朝向作为向量计算与立方体贴图交点,得到背景颜色信息
+
 

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

@@ -136,7 +136,9 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="src\Util\SkyBox.cpp" />
     <ClCompile Include="src\testModule\TestFrameBuffer.cpp" />
+    <ClCompile Include="src\testModule\TestSkyBox.cpp" />
     <ClCompile Include="src\Util\BaseLight.cpp" />
     <ClCompile Include="src\testModule\TestModelV1.cpp" />
     <ClCompile Include="src\Util\Model.cpp" />
@@ -167,7 +169,9 @@
     <ClCompile Include="src\Util\Texture.cpp" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="src\Util\SkyBox.h" />
     <ClInclude Include="src\testModule\TestFrameBuffer.h" />
+    <ClInclude Include="src\testModule\TestSkyBox.h" />
     <ClInclude Include="src\Util\BaseLight.h" />
     <ClInclude Include="src\testModule\TestModelV1.h" />
     <ClInclude Include="src\Util\Model.h" />
@@ -491,6 +495,8 @@
     <None Include="res\shader\Light\Vertex.vert" />
     <None Include="res\shader\model\model.frag" />
     <None Include="res\shader\model\model.vert" />
+    <None Include="res\shader\SkyBox\skybox.frag" />
+    <None Include="res\shader\SkyBox\skybox.vert" />
     <None Include="res\shader\TextPosition\Fragment.frag" />
     <None Include="res\shader\TextPosition\Vertex.vert" />
     <None Include="src\third\glm\detail\func_common.inl" />

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

@@ -102,6 +102,12 @@
     <ClCompile Include="src\testModule\TestFrameBuffer.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="src\testModule\TestSkyBox.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Util\SkyBox.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\third\imgui\imstb_truetype.h">
@@ -1040,6 +1046,12 @@
     <ClInclude Include="src\testModule\TestFrameBuffer.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="src\testModule\TestSkyBox.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Util\SkyBox.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\third\glm\detail\func_common.inl">
@@ -1462,6 +1474,8 @@
     <None Include="res\shader\FrameBuffer\fb.vert" />
     <None Include="res\shader\TextPosition\Fragment.frag" />
     <None Include="res\shader\TextPosition\Vertex.vert" />
+    <None Include="res\shader\SkyBox\skybox.frag" />
+    <None Include="res\shader\SkyBox\skybox.vert" />
   </ItemGroup>
   <ItemGroup>
     <Image Include="res\textures\test.jpg">

+ 7 - 2
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/imgui.ini

@@ -10,7 +10,7 @@ Collapsed=0
 
 [Window][Common Test Title]
 Pos=6,6
-Size=144,205
+Size=145,177
 Collapsed=0
 
 [Window][ClearColor]
@@ -29,7 +29,12 @@ Size=418,267
 Collapsed=0
 
 [Window][Model]
-Pos=335,51
+Pos=384,44
 Size=396,162
+Collapsed=1
+
+[Window][SkyBox]
+Pos=353,55
+Size=330,99
 Collapsed=0
 

+ 11 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/SkyBox/skybox.frag

@@ -0,0 +1,11 @@
+#version 330 core
+
+layout(location = 0) out vec4 o_color;
+
+in vec3 v_TexCoord;
+
+uniform samplerCube cubeTexture;
+
+void main() {
+    o_color = texture(cubeTexture, v_TexCoord);
+}

+ 14 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/SkyBox/skybox.vert

@@ -0,0 +1,14 @@
+#version 330 core
+
+layout(location = 0) in vec3 inPosition;
+
+out vec3 v_TexCoord;
+
+uniform mat4 projection;
+uniform mat4 view;
+
+void main() {
+    v_TexCoord = inPosition;
+    vec4 pos = projection * view * vec4(inPosition, 1.0);
+    gl_Position = pos.xyww;
+}

BIN
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/back.jpg


BIN
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/bottom.jpg


BIN
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/front.jpg


BIN
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/left.jpg


BIN
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/right.jpg


BIN
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/textures/skybox/top.jpg


+ 45 - 26
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/CommonData.h

@@ -34,32 +34,51 @@ enum ETextureType
 };
 
 static std::map<ETextureType, std::string> G_TextureTypeToString = {
-	{ ETextureType::E_NONE  , "NONE " },
-	{ ETextureType::E_DIFFUSE  , "DIFFUSE " },
-	{ ETextureType::E_SPECULAR  , "SPECULAR " },
-	{ ETextureType::E_AMBIENT  , "AMBIENT " },
-	{ ETextureType::E_EMISSIVE  , "EMISSIVE " },
-	{ ETextureType::E_HEIGHT  , "HEIGHT " },
-	{ ETextureType::E_NORMALS  , "NORMALS " },
-	{ ETextureType::E_SHININESS  , "SHININESS " },
-	{ ETextureType::E_OPACITY  , "OPACITY " },
-	{ ETextureType::E_DISPLACEMENT  , "DISPLACEMENT " },
-	{ ETextureType::E_LIGHTMAP  , "LIGHTMAP " },
-	{ ETextureType::E_REFLECTION  , "REFLECTION " },
-	{ ETextureType::E_BASE_COLOR  , "BASE_COLOR " },
-	{ ETextureType::E_NORMAL_CAMERA  , "NORMAL_CAMERA " },
-	{ ETextureType::E_EMISSION_COLOR  , "EMISSION_COLOR " },
-	{ ETextureType::E_METALNESS  , "METALNESS " },
-	{ ETextureType::E_DIFFUSE_ROUGHNESS  , "DIFFUSE_ROUGHNESS " },
-	{ ETextureType::E_AMBIENT_OCCLUSION  , "AMBIENT_OCCLUSION " },
-	{ ETextureType::E_UNKNOWN  , "UNKNOWN " },
-	{ ETextureType::E_SHEEN  , "SHEEN " },
-	{ ETextureType::E_CLEARCOAT  , "CLEARCOAT " },
-	{ ETextureType::E_TRANSMISSION  , "TRANSMISSION " },
-	{ ETextureType::E_MAYA_BASE  , "MAYA_BASE " },
-	{ ETextureType::E_MAYA_SPECULAR  , "MAYA_SPECULAR " },
-	{ ETextureType::E_MAYA_SPECULAR_COLOR  , "MAYA_SPECULAR_COLOR " },
-	{ ETextureType::E_MAYA_SPECULAR_ROUGHNESS  , "MAYA_SPECULAR_ROUGHNESS " },
+	{ ETextureType::E_NONE,							"NONE " },
+	{ ETextureType::E_DIFFUSE,						"DIFFUSE " },
+	{ ETextureType::E_SPECULAR,						"SPECULAR " },
+	{ ETextureType::E_AMBIENT,						"AMBIENT " },
+	{ ETextureType::E_EMISSIVE,						"EMISSIVE " },
+	{ ETextureType::E_HEIGHT,						"HEIGHT " },
+	{ ETextureType::E_NORMALS,						"NORMALS " },
+	{ ETextureType::E_SHININESS,					"SHININESS " },
+	{ ETextureType::E_OPACITY,						"OPACITY " },
+	{ ETextureType::E_DISPLACEMENT,					"DISPLACEMENT " },
+	{ ETextureType::E_LIGHTMAP,						"LIGHTMAP " },
+	{ ETextureType::E_REFLECTION,					"REFLECTION " },
+	{ ETextureType::E_BASE_COLOR,					"BASE_COLOR " },
+	{ ETextureType::E_NORMAL_CAMERA,				"NORMAL_CAMERA " },
+	{ ETextureType::E_EMISSION_COLOR,				"EMISSION_COLOR " },
+	{ ETextureType::E_METALNESS,					"METALNESS " },
+	{ ETextureType::E_DIFFUSE_ROUGHNESS,			"DIFFUSE_ROUGHNESS " },
+	{ ETextureType::E_AMBIENT_OCCLUSION,			"AMBIENT_OCCLUSION " },
+	{ ETextureType::E_UNKNOWN,						"UNKNOWN " },
+	{ ETextureType::E_SHEEN,						"SHEEN " },
+	{ ETextureType::E_CLEARCOAT,					"CLEARCOAT " },
+	{ ETextureType::E_TRANSMISSION,					"TRANSMISSION " },
+	{ ETextureType::E_MAYA_BASE,					"MAYA_BASE " },
+	{ ETextureType::E_MAYA_SPECULAR,				"MAYA_SPECULAR " },
+	{ ETextureType::E_MAYA_SPECULAR_COLOR,			"MAYA_SPECULAR_COLOR " },
+	{ ETextureType::E_MAYA_SPECULAR_ROUGHNESS,		"MAYA_SPECULAR_ROUGHNESS " },
+};
+
+enum class ESkyBoxTextureType : uint8_t
+{
+	E_Right,			// 右
+	E_Left,				// 左
+	E_Top,				// 上
+	E_Bottom,			// 下
+	E_Front,			// 前
+	E_Back,				// 后
+};
+
+static std::map<ESkyBoxTextureType, unsigned int> G_CubeTextureTypeMap = {
+	{ ESkyBoxTextureType::E_Right	, GL_TEXTURE_CUBE_MAP_POSITIVE_X },
+	{ ESkyBoxTextureType::E_Left	, GL_TEXTURE_CUBE_MAP_NEGATIVE_X },
+	{ ESkyBoxTextureType::E_Top		, GL_TEXTURE_CUBE_MAP_POSITIVE_Y },
+	{ ESkyBoxTextureType::E_Bottom	, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y },
+	{ ESkyBoxTextureType::E_Front	, GL_TEXTURE_CUBE_MAP_POSITIVE_Z },
+	{ ESkyBoxTextureType::E_Back	, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z },
 };
 
 // 顶点信息 v0 版本 后续根据需要可能新增 v1、v2 ...

+ 118 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/SkyBox.cpp

@@ -0,0 +1,118 @@
+#include "SkyBox.h"
+
+SkyBox::SkyBox()
+{
+	m_TexturePath = {
+		{ ESkyBoxTextureType::E_Right	, "res/textures/skybox/right.jpg"},
+		{ ESkyBoxTextureType::E_Left	, "res/textures/skybox/left.jpg"},
+		{ ESkyBoxTextureType::E_Top		, "res/textures/skybox/top.jpg"},
+		{ ESkyBoxTextureType::E_Bottom	, "res/textures/skybox/bottom.jpg"},
+		{ ESkyBoxTextureType::E_Front	, "res/textures/skybox/front.jpg"},
+		{ ESkyBoxTextureType::E_Back	, "res/textures/skybox/back.jpg"},
+	};
+}
+
+SkyBox::~SkyBox()
+{
+    glDeleteVertexArrays(1, &m_VAO);
+}
+
+void SkyBox::Init(const std::map<ESkyBoxTextureType, std::string> InTexturePath)
+{
+	m_TexturePath = InTexturePath;
+
+	Init();
+}
+
+void SkyBox::Draw(const glm::mat4& view, const glm::mat4& projection)
+{
+    const int TextureSlot = 1;
+    m_cubeImage.BindCubeTexture(TextureSlot);
+    m_skyShader.Bind();
+    m_skyShader.SetUniform1i("cubeTexture", TextureSlot);
+    m_skyShader.SetUniformMat4f("projection", projection);
+    m_skyShader.SetUniformMat4f("view", view);
+
+    glBindVertexArray(m_VAO);
+    glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
+    glBindVertexArray(GL_ZERO);
+}
+
+void SkyBox::InitVAO()
+{
+    float skyboxVertices[] = {
+        -1.0f,  1.0f, -1.0f,
+        -1.0f, -1.0f, -1.0f,
+         1.0f, -1.0f, -1.0f,
+         1.0f, -1.0f, -1.0f,
+         1.0f,  1.0f, -1.0f,
+        -1.0f,  1.0f, -1.0f,
+
+        -1.0f, -1.0f,  1.0f,
+        -1.0f, -1.0f, -1.0f,
+        -1.0f,  1.0f, -1.0f,
+        -1.0f,  1.0f, -1.0f,
+        -1.0f,  1.0f,  1.0f,
+        -1.0f, -1.0f,  1.0f,
+
+         1.0f, -1.0f, -1.0f,
+         1.0f, -1.0f,  1.0f,
+         1.0f,  1.0f,  1.0f,
+         1.0f,  1.0f,  1.0f,
+         1.0f,  1.0f, -1.0f,
+         1.0f, -1.0f, -1.0f,
+
+        -1.0f, -1.0f,  1.0f,
+        -1.0f,  1.0f,  1.0f,
+         1.0f,  1.0f,  1.0f,
+         1.0f,  1.0f,  1.0f,
+         1.0f, -1.0f,  1.0f,
+        -1.0f, -1.0f,  1.0f,
+
+        -1.0f,  1.0f, -1.0f,
+         1.0f,  1.0f, -1.0f,
+         1.0f,  1.0f,  1.0f,
+         1.0f,  1.0f,  1.0f,
+        -1.0f,  1.0f,  1.0f,
+        -1.0f,  1.0f, -1.0f,
+
+        -1.0f, -1.0f, -1.0f,
+        -1.0f, -1.0f,  1.0f,
+         1.0f, -1.0f, -1.0f,
+         1.0f, -1.0f, -1.0f,
+        -1.0f, -1.0f,  1.0f,
+         1.0f, -1.0f,  1.0f
+    };
+
+    glGenVertexArrays(1, &m_VAO);
+    glBindVertexArray(m_VAO);
+
+    GLuint VBO;
+    glGenBuffers(1, &VBO);
+    glBindBuffer(GL_ARRAY_BUFFER, VBO);
+    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
+
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+
+    // ½â³ý°ó¶¨¹ØÏµ
+    glBindVertexArray(GL_ZERO);
+}
+
+void SkyBox::InitImage()
+{
+    m_cubeImage.InitWithSkyBox(m_TexturePath);
+}
+
+void SkyBox::InitShader()
+{
+    m_skyShader.Init("res/shader/SkyBox/skybox.vert", "res/shader/SkyBox/skybox.frag");
+}
+
+void SkyBox::Init()
+{
+    InitImage();
+    InitVAO();
+    InitShader();
+}
+

+ 32 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/SkyBox.h

@@ -0,0 +1,32 @@
+#pragma once
+#include "CommonData.h"
+
+#include "Texture.h"
+#include "Shader.h"
+
+
+class SkyBox
+{
+public:
+	SkyBox();
+	~SkyBox();
+
+	void Init();
+	void Init(const std::map<ESkyBoxTextureType, std::string> InTexturePath);
+
+	void Draw(const glm::mat4& view, const glm::mat4& projection);
+
+protected:
+	void InitVAO();
+	void InitImage();
+	void InitShader();
+
+private:
+	Texture m_cubeImage;
+	Shader m_skyShader;
+
+	GLuint m_VAO;
+
+	std::map<ESkyBoxTextureType, std::string> m_TexturePath;
+};
+

+ 34 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Texture.cpp

@@ -135,6 +135,40 @@ void Texture::InitWithModelInnterTexture(const aiTexture* inTexture)
 	image_data = nullptr;
 }
 
+void Texture::InitWithSkyBox(const std::map<ESkyBoxTextureType, std::string>& InTexturesPath)
+{
+	glGenTextures(1, &m_TextureId);
+	glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId);
+
+	stbi_set_flip_vertically_on_load(1);
+
+	for (const auto& TextureItem : InTexturesPath)
+	{
+		unsigned char* image_data = nullptr;
+		image_data = stbi_load(TextureItem.second.c_str(), &m_Width, &m_Height, &m_BPP, 0);
+		if (image_data != nullptr)
+		{
+			GL_CALL(glTexImage2D(G_CubeTextureTypeMap[TextureItem.first], 0, GL_RGB, m_Width, m_Height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data));
+		}
+		stbi_image_free(image_data);
+		image_data = nullptr;
+	}
+
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+}
+
+void Texture::BindCubeTexture(GLuint slot)
+{
+	m_LastBindSlot = slot;
+	GL_CALL(glActiveTexture(GL_TEXTURE0 + slot));
+	GL_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId));
+}
+
 void Texture::Bind(GLuint slot)
 {
 	m_LastBindSlot = slot;

+ 4 - 1
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Texture.h

@@ -1,5 +1,6 @@
 #pragma once
-#include "CommonHead.h"
+//#include "CommonHead.h"
+#include "CommonData.h"
 
 class aiTexture;
 
@@ -14,7 +15,9 @@ public:
 	void Init(const std::string& filePath);
 	void InitWithModelTexture(const std::string& filePath);
 	void InitWithModelInnterTexture(const aiTexture* inTexture);
+	void InitWithSkyBox(const std::map<ESkyBoxTextureType, std::string>& InTexturesPath);
 
+	void BindCubeTexture(GLuint slot = 0);
 	void Bind(GLuint slot = 0);
 	void UnBind();
 

+ 108 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestSkyBox.cpp

@@ -0,0 +1,108 @@
+#include "TestSkyBox.h"
+#include "../Util/RenderSettings.h"
+#include "TestModuleManager.h"
+
+TestSkyBox TestSkyBox::_self;
+
+void TestSkyBox::OnEnter(GLFWwindow* window)
+{	// 启动深度测试
+	glEnable(GL_DEPTH_TEST);
+
+	// 初始化 shader
+	m_ModelShader.Init("res/shader/model/model.vert", "res/shader/model/model.frag");
+	m_packageModel.Init("res/model/Miku/miku_prefab.fbx");
+
+	m_Camera.SetLocation(glm::vec3(0.0f, 0.0f, 3.0f));
+	BindMouse(window);
+
+	InitSkyBox();
+}
+
+void TestSkyBox::OnExit(GLFWwindow* window)
+{
+	glfwSetWindowUserPointer(window, nullptr);
+	UnBindMouse(window);
+}
+
+void TestSkyBox::UpdateLogic(float delayTime)
+{
+	m_view = m_Camera.GetView();
+	m_Camera.SetMoveSpeed(1);
+	m_Camera.SetRotateSpeed(1);
+
+	// 可能会更新窗口视口大小 每帧更新一下
+	m_proj = glm::perspective(glm::radians(45.0f), (float)RSI->ViewportHeight / (float)RSI->ViewportWidth, 0.1f, 100.0f);
+}
+
+void TestSkyBox::ClearRender(GLFWwindow* window)
+{
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+void TestSkyBox::Render(GLFWwindow* window)
+{
+	m_ModelShader.Bind();
+
+
+	auto CameraLocation = m_Camera.GetCameraLocation();
+
+	m_ModelShader.SetUniformMat4f("model", glm::mat4(1.0f));
+	m_ModelShader.SetUniformMat4f("view", m_view);
+	m_ModelShader.SetUniformMat4f("projection", m_proj);
+	m_ModelShader.SetUniform3f("lightPos", 0.0f, 0.0f, 0.0f);
+	m_ModelShader.SetUniform3f("viewPos", CameraLocation.x, CameraLocation.y, CameraLocation.z);
+	m_ModelShader.SetUniform1i("shineness", 4);
+
+	m_packageModel.Draw(m_ModelShader);
+
+	m_sky.Draw(m_view, m_proj);
+}
+
+void TestSkyBox::UpdateImGUI(GLFWwindow* window)
+{
+	const auto& io = ImGui::GetIO();
+
+	ImGui::Begin("SkyBox");
+
+	ImGui::End();
+}
+
+void TestSkyBox::InputProcess(GLFWwindow* window)
+{
+	TestWithMouseBase::InputProcess(window);
+
+	m_Camera.InputProcess(window);
+
+	if (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS)
+	{
+		m_bLeftAltPress = true;
+		UnBindMouse(window);
+	}
+	else if (m_bLeftAltPress) {
+		// 因为当前状况 如果不按下 左 alt,每帧都会导致该函数触发,加个判断防止重复触发
+		m_bLeftAltPress = false;
+		BindMouse(window);
+	}
+}
+
+void TestSkyBox::MouseCallback(GLFWwindow* window, double xpos, double ypos)
+{
+	m_Camera.MouseCallback(window, xpos, ypos);
+}
+
+void TestSkyBox::BindMouse(GLFWwindow* window)
+{
+	m_Camera.SetFirstMouse(true);
+	TestWithMouseBase::BindMouse(window);
+}
+
+void TestSkyBox::UnBindMouse(GLFWwindow* window)
+{
+	m_Camera.SetFirstMouse(false);
+	TestWithMouseBase::UnBindMouse(window);
+}
+
+void TestSkyBox::InitSkyBox()
+{
+	m_sky.Init();
+}

+ 53 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestSkyBox.h

@@ -0,0 +1,53 @@
+#pragma once
+#include "TestWithMouseBase.h"
+#include "../Util/CommonData.h"
+
+#include "../Util/Shader.h"
+#include "../Util/Texture.h"
+#include "../Util/Camera.h"
+#include "../Util/Model.h"
+
+#include "../Util/BaseLight.h"
+
+#include "../Util/SkyBox.h"
+
+class TestSkyBox : public TestWithMouseBase
+{
+public:
+	TestSkyBox() : TestWithMouseBase("TestSkyBox") {}
+
+public:
+	virtual void OnEnter(GLFWwindow* window) override;
+	virtual void OnExit(GLFWwindow* window) override;
+
+	virtual void UpdateLogic(float delayTime) override;
+	virtual void ClearRender(GLFWwindow* window) override;
+	virtual void Render(GLFWwindow* window) override;
+	virtual void UpdateImGUI(GLFWwindow* window) override;
+
+	virtual void InputProcess(GLFWwindow* window) override;
+
+	virtual void MouseCallback(GLFWwindow* window, double xpos, double ypos) override;
+
+	virtual void BindMouse(GLFWwindow* window) override;
+	virtual void UnBindMouse(GLFWwindow* window) override;
+
+protected:
+	void InitSkyBox();
+
+private:
+	glm::mat4 m_model = glm::mat4(1.0f);		// 模型矩阵
+	glm::mat4 m_view = glm::mat4(1.0f);			// 视图矩阵
+	glm::mat4 m_proj = glm::mat4(1.0f);			// 投影矩阵
+
+	Camera m_Camera;
+	bool m_bLeftAltPress = false;
+
+	SkyBox m_sky;
+
+	Shader m_ModelShader;
+	Model m_packageModel;
+
+	static TestSkyBox _self;
+};
+