重构项目,为后续开发铺路
This commit is contained in:
parent
bd2f846a34
commit
7bd5d7c13d
|
|
@ -3,5 +3,7 @@
|
||||||
<Platform Name="x64" />
|
<Platform Name="x64" />
|
||||||
<Platform Name="x86" />
|
<Platform Name="x86" />
|
||||||
</Configurations>
|
</Configurations>
|
||||||
<Project Path="CPU-Software-Renderer/CPU-Software-Renderer.vcxproj" Id="937b923d-dd0c-41ae-81eb-af978170b0ca" />
|
<Project Path="CPU-Software-Renderer/CPU-Software-Renderer.vcxproj" Id="937b923d-dd0c-41ae-81eb-af978170b0ca">
|
||||||
|
<Platform Solution="Debug|x86" Project="x64" />
|
||||||
|
</Project>
|
||||||
</Solution>
|
</Solution>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Asset
|
||||||
|
{
|
||||||
|
class ObjLoader
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -77,10 +77,13 @@
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<AdditionalIncludeDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Asset;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Core;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Math;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Rasterizer;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\RenderData;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Scene;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Shading;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
|
@ -92,10 +95,13 @@
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<AdditionalIncludeDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Asset;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Core;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Math;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Rasterizer;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\RenderData;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Scene;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Shading;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
|
@ -105,7 +111,7 @@
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<AdditionalIncludeDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Asset;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Core;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Math;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Rasterizer;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\RenderData;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Scene;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Shading;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|
@ -123,26 +129,52 @@
|
||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<AdditionalIncludeDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Asset;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Core;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Math;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Rasterizer;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\RenderData;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Scene;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\Shading;D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>D:\source\CPU-Software-Renderer\CPU-Software-Renderer\libs\SDL2\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Color.cpp" />
|
<ClCompile Include="Asset\ObjLoader.cpp" />
|
||||||
|
<ClCompile Include="Core\DepthBuffer.cpp" />
|
||||||
|
<ClCompile Include="Core\FrameBuffer.cpp" />
|
||||||
|
<ClCompile Include="Core\Renderer.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="Rasterization.cpp" />
|
<ClCompile Include="Rasterizer\Rasterizer.cpp" />
|
||||||
|
<ClCompile Include="Rasterizer\TriangleRasterizer.cpp" />
|
||||||
|
<ClCompile Include="Shading\BlinnPhongShader.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="TODO.md" />
|
<None Include="TODO.md" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Color.h" />
|
<ClInclude Include="Asset\ObjLoader.h" />
|
||||||
<ClInclude Include="Rasterization.h" />
|
<ClInclude Include="Core\DepthBuffer.h" />
|
||||||
<ClInclude Include="StructType.h" />
|
<ClInclude Include="Core\FrameBuffer.h" />
|
||||||
|
<ClInclude Include="Core\Renderer.h" />
|
||||||
|
<ClInclude Include="Math\MathUtil.h" />
|
||||||
|
<ClInclude Include="Math\Matrix4x4.h" />
|
||||||
|
<ClInclude Include="Math\Vector2.h" />
|
||||||
|
<ClInclude Include="Math\Vector3.h" />
|
||||||
|
<ClInclude Include="Math\Vector4.h" />
|
||||||
|
<ClInclude Include="Rasterizer\Rasterizer.h" />
|
||||||
|
<ClInclude Include="Rasterizer\TriangleRasterizer.h" />
|
||||||
|
<ClInclude Include="RenderData\BoundingBox.h" />
|
||||||
|
<ClInclude Include="RenderData\Color.h" />
|
||||||
|
<ClInclude Include="RenderData\Triangle.h" />
|
||||||
|
<ClInclude Include="Scene\Camera.h" />
|
||||||
|
<ClInclude Include="Scene\Mesh.h" />
|
||||||
|
<ClInclude Include="Scene\Model.h" />
|
||||||
|
<ClInclude Include="Scene\Transform.h" />
|
||||||
|
<ClInclude Include="Scene\Vertex.h" />
|
||||||
|
<ClInclude Include="Shading\BlinnPhongShader.h" />
|
||||||
|
<ClInclude Include="Shading\ShaderTypes.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,64 @@
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="头文件\Core">
|
||||||
|
<UniqueIdentifier>{e546c002-17ba-4911-9a70-a1cf7ce337fd}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件\Math">
|
||||||
|
<UniqueIdentifier>{b92096d9-3d39-4064-b9a2-efa279ad0775}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件\Scene">
|
||||||
|
<UniqueIdentifier>{7b6f5c6b-60bb-46f2-925b-65346e4d8c4b}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件\Shading">
|
||||||
|
<UniqueIdentifier>{1aa3c6ac-a580-480c-a2fe-2d57c98693ff}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件\Rasterizer">
|
||||||
|
<UniqueIdentifier>{a7d67eb7-b4bc-4b5a-86f2-e80bcd1518d5}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件\Asset">
|
||||||
|
<UniqueIdentifier>{55224e49-7917-4fee-9a61-f1c14ebf8d5e}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="源文件\Core">
|
||||||
|
<UniqueIdentifier>{6eda961b-ec6a-4670-b093-be46b27fdeb7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="源文件\Asset">
|
||||||
|
<UniqueIdentifier>{4345cc0e-3d61-4dd9-b37f-4b42c30aa8d3}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="源文件\Rasterizer">
|
||||||
|
<UniqueIdentifier>{4b52509e-dde8-45e0-aeb3-d18131b94265}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="源文件\Shading">
|
||||||
|
<UniqueIdentifier>{1644176d-c2fe-404b-9f42-45eb0bc85222}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件\RenderData">
|
||||||
|
<UniqueIdentifier>{c77ae566-281a-4d76-80bd-41496deb0aeb}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Color.cpp">
|
<ClCompile Include="Core\DepthBuffer.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件\Core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Rasterization.cpp">
|
<ClCompile Include="Core\FrameBuffer.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件\Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Core\Renderer.cpp">
|
||||||
|
<Filter>源文件\Core</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Asset\ObjLoader.cpp">
|
||||||
|
<Filter>源文件\Asset</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Shading\BlinnPhongShader.cpp">
|
||||||
|
<Filter>源文件\Shading</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Rasterizer\Rasterizer.cpp">
|
||||||
|
<Filter>源文件\Rasterizer</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Rasterizer\TriangleRasterizer.cpp">
|
||||||
|
<Filter>源文件\Rasterizer</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -31,14 +79,68 @@
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Color.h">
|
<ClInclude Include="Core\DepthBuffer.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件\Core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="StructType.h">
|
<ClInclude Include="Core\FrameBuffer.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件\Core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Rasterization.h">
|
<ClInclude Include="Core\Renderer.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件\Core</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Math\MathUtil.h">
|
||||||
|
<Filter>头文件\Math</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Math\Matrix4x4.h">
|
||||||
|
<Filter>头文件\Math</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Math\Vector2.h">
|
||||||
|
<Filter>头文件\Math</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Math\Vector3.h">
|
||||||
|
<Filter>头文件\Math</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Math\Vector4.h">
|
||||||
|
<Filter>头文件\Math</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Scene\Camera.h">
|
||||||
|
<Filter>头文件\Scene</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Scene\Mesh.h">
|
||||||
|
<Filter>头文件\Scene</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Scene\Model.h">
|
||||||
|
<Filter>头文件\Scene</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Scene\Transform.h">
|
||||||
|
<Filter>头文件\Scene</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Scene\Vertex.h">
|
||||||
|
<Filter>头文件\Scene</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Shading\BlinnPhongShader.h">
|
||||||
|
<Filter>头文件\Shading</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Shading\ShaderTypes.h">
|
||||||
|
<Filter>头文件\Shading</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Rasterizer\Rasterizer.h">
|
||||||
|
<Filter>头文件\Rasterizer</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Rasterizer\TriangleRasterizer.h">
|
||||||
|
<Filter>头文件\Rasterizer</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Asset\ObjLoader.h">
|
||||||
|
<Filter>头文件\Asset</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RenderData\Triangle.h">
|
||||||
|
<Filter>头文件\RenderData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RenderData\Color.h">
|
||||||
|
<Filter>头文件\RenderData</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="RenderData\BoundingBox.h">
|
||||||
|
<Filter>头文件\RenderData</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
#include "Color.h"
|
|
||||||
|
|
||||||
Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
|
||||||
{
|
|
||||||
this->r = r;
|
|
||||||
this->g = g;
|
|
||||||
this->b = b;
|
|
||||||
this->a = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color::Color(uint8_t r, uint8_t g, uint8_t b)
|
|
||||||
{
|
|
||||||
Color(r, g, b, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color::Color(Color& other)
|
|
||||||
{
|
|
||||||
this->r = other.r;
|
|
||||||
this->g = other.g;
|
|
||||||
this->b = other.b;
|
|
||||||
this->a = other.a;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include<cstdint>
|
|
||||||
|
|
||||||
class Color
|
|
||||||
{
|
|
||||||
uint8_t r;
|
|
||||||
uint8_t g;
|
|
||||||
uint8_t b;
|
|
||||||
uint8_t a;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
|
||||||
Color(uint8_t r, uint8_t g, uint8_t b);
|
|
||||||
Color(Color& other);
|
|
||||||
|
|
||||||
uint8_t GetR() const { return r; }
|
|
||||||
void SetR(const uint8_t r) { this->r = r; }
|
|
||||||
|
|
||||||
uint8_t GetG() const { return g; }
|
|
||||||
void SetG(const uint8_t g) { this->g = g; }
|
|
||||||
|
|
||||||
uint8_t GetB() const { return b; }
|
|
||||||
void SetB(const uint8_t b) { this->b = b; }
|
|
||||||
|
|
||||||
uint8_t GetA() const { return a; }
|
|
||||||
void SetA(const uint8_t a) { this->a = a; }
|
|
||||||
|
|
||||||
operator uint32_t() const
|
|
||||||
{
|
|
||||||
return (r << 24) | (g << 16) | (b << 8) | a;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class DepthBuffer
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
using namespace Math;
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
void FrameBuffer::clear(const uint32_t color)
|
||||||
|
{
|
||||||
|
std::fill(buffer.begin(), buffer.end(), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FrameBuffer::set_pixel(const int32_t x, const int32_t y, const uint32_t color)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= width || y < 0 || y >= height)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: Attempting to set pixel at (" << x << ", " << y << ") which is out of bounds." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t index = static_cast<size_t>(y) * width + x;
|
||||||
|
buffer.at(index) = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Color.h"
|
||||||
|
#include "Vector2.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class FrameBuffer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int32_t width;
|
||||||
|
int32_t height;
|
||||||
|
std::vector<uint32_t> buffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t total_pixels() const { return buffer.size(); }
|
||||||
|
|
||||||
|
void* get_buffer() const { return (void*)buffer.data(); }
|
||||||
|
|
||||||
|
FrameBuffer(int32_t width, int32_t height) :width(width), height(height), buffer(std::vector<uint32_t>(width * height, 0)) {}
|
||||||
|
|
||||||
|
void clear(const RenderData::Color& color)
|
||||||
|
{
|
||||||
|
clear(color.to_rgba());
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(const uint32_t color);
|
||||||
|
|
||||||
|
void set_pixel(const int32_t x, const int32_t y, const RenderData::Color& color)
|
||||||
|
{
|
||||||
|
set_pixel(Math::Vector2Int(x, y), color.to_rgba());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_pixel(const Math::Vector2Int position, const uint32_t color)
|
||||||
|
{
|
||||||
|
set_pixel(position.x, position.y, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_pixel(const int32_t x, const int32_t y, const uint32_t color);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class Renderer
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
|
class MathUtil
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
|
class Matrix4x4
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <utility>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
|
struct Vector2Int
|
||||||
|
{
|
||||||
|
int32_t x = 0;
|
||||||
|
int32_t y = 0;
|
||||||
|
|
||||||
|
Vector2Int() : x(0), y(0) {}
|
||||||
|
Vector2Int(int32_t x, int32_t y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交换当前 Vector2Int 对象与另一个 Vector2Int 对象的 x 和 y 的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">要交换的对象</param>
|
||||||
|
static void swap(Vector2Int& vec1, Vector2Int& vec2)
|
||||||
|
{
|
||||||
|
std::swap(vec1.x, vec2.x);
|
||||||
|
std::swap(vec1.y, vec2.y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vector2
|
||||||
|
{
|
||||||
|
float x = 0.0f;
|
||||||
|
float y = 0.0f;
|
||||||
|
|
||||||
|
Vector2() : x(0), y(0) {}
|
||||||
|
Vector2(float x, float y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交换当前 Vector2 对象与另一个 Vector2 对象的 x 和 y 的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">要交换的对象</param>
|
||||||
|
static void swap(Vector2& vec1, Vector2& vec2)
|
||||||
|
{
|
||||||
|
std::swap(vec1.x, vec2.x);
|
||||||
|
std::swap(vec1.y, vec2.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2Int to_vector2Int() const
|
||||||
|
{
|
||||||
|
return Vector2Int(static_cast<int32_t>(std::lround(x)), static_cast<int32_t>(std::lround(y)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
|
struct Vector3
|
||||||
|
{
|
||||||
|
float x = 0.0f;
|
||||||
|
float y = 0.0f;
|
||||||
|
float z = 0.0f;
|
||||||
|
|
||||||
|
Vector3() : x(0), y(0), z(0) {}
|
||||||
|
Vector3(float x, float y, float z) : x(x), y(y), z(z) {}
|
||||||
|
|
||||||
|
float magnitude() const
|
||||||
|
{
|
||||||
|
return std::sqrt(x * x + y * y + z * z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
|
class Vector4
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
#include "Rasterization.h"
|
|
||||||
#include "StructType.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cmath>
|
|
||||||
using namespace CustomStructs;
|
|
||||||
|
|
||||||
void Rasterization::DrawLineHorizontal(Vector2Int v0, Vector2Int v1, Color color)
|
|
||||||
{
|
|
||||||
if (v0.x > v1.x) Vector2Int::swap(v0, v1);
|
|
||||||
|
|
||||||
int32_t dx = v1.x - v0.x;
|
|
||||||
int32_t dy = v1.y - v0.y;
|
|
||||||
|
|
||||||
int32_t dir = dy < 0 ? -1 : 1;
|
|
||||||
dy *= dir;
|
|
||||||
|
|
||||||
if (dx == 0) return;
|
|
||||||
|
|
||||||
int32_t y = v0.y;
|
|
||||||
int32_t p = 2 * dy - dx;
|
|
||||||
for (int32_t x = v0.x; x <= v1.x; x++)
|
|
||||||
{
|
|
||||||
SetPixel(Vector2Int(x, y), color);
|
|
||||||
// 当 p >= 0 时,取上方像素点
|
|
||||||
if (p >= 0)
|
|
||||||
{
|
|
||||||
y += dir;
|
|
||||||
p -= 2 * dx;
|
|
||||||
}
|
|
||||||
// 当 p < 0 时,取下方像素点
|
|
||||||
p += 2 * dy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rasterization::DrawLineVertical(Vector2Int v0, Vector2Int v1, Color color)
|
|
||||||
{
|
|
||||||
if (v0.y > v1.y) Vector2Int::swap(v0, v1);
|
|
||||||
|
|
||||||
int32_t dx = v1.x - v0.x;
|
|
||||||
int32_t dy = v1.y - v0.y;
|
|
||||||
|
|
||||||
int32_t dir = dx < 0 ? -1 : 1;
|
|
||||||
dx *= dir;
|
|
||||||
|
|
||||||
if (dy == 0) return;
|
|
||||||
|
|
||||||
int32_t x = v0.x;
|
|
||||||
int32_t p = 2 * dx - dy;
|
|
||||||
for (int32_t y = v0.y; y <= v1.y; y++)
|
|
||||||
{
|
|
||||||
SetPixel(Vector2Int(x, y), color);
|
|
||||||
// 当 p >= 0 时,取上方像素点
|
|
||||||
if (p >= 0)
|
|
||||||
{
|
|
||||||
x += dir;
|
|
||||||
p -= 2 * dy;
|
|
||||||
}
|
|
||||||
// 当 p < 0 时,取下方像素点
|
|
||||||
p += 2 * dx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在给定的起始点和结束点之间绘制一条线段,并使用指定的颜色填充
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="v0">直线顶点 1</param>
|
|
||||||
/// <param name="v1">直线顶点 2</param>
|
|
||||||
/// <param name="color">绘制的颜色</param>
|
|
||||||
/// <remarks>
|
|
||||||
/// bresenham 画线算法
|
|
||||||
/// </remarks>
|
|
||||||
void Rasterization::DrawLine(Vector2Int v0, Vector2Int v1, Color color)
|
|
||||||
{
|
|
||||||
int32_t x0 = v0.x, y0 = v0.y;
|
|
||||||
int32_t x1 = v1.x, y1 = v1.y;
|
|
||||||
|
|
||||||
if (std::abs(x1 - x0) > std::abs(y1 - y0))
|
|
||||||
{
|
|
||||||
DrawLineHorizontal(v0, v1, color);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawLineVertical(v0, v1, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rasterization::Clear(const Color color)
|
|
||||||
{
|
|
||||||
uint32_t colorValue = static_cast<uint32_t>(color);
|
|
||||||
std::fill(frameBuffer.begin(), frameBuffer.end(), colorValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rasterization::SetPixel(const Vector2Int pos, const Color color)
|
|
||||||
{
|
|
||||||
uint32_t colorValue = static_cast<uint32_t>(color);
|
|
||||||
if (pos.x < 0 || pos.y < 0 || pos.x >= width || pos.y >= height) return;
|
|
||||||
const size_t pixelIndex = static_cast<size_t>(pos.y) * static_cast<size_t>(width) + static_cast<size_t>(pos.x);
|
|
||||||
frameBuffer[pixelIndex] = colorValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rasterization::DrawWireTriangle(const Vector2Int v0, const Vector2Int v1, const Vector2Int v2, Color color)
|
|
||||||
{
|
|
||||||
DrawLine(v0, v1, color);
|
|
||||||
DrawLine(v0, v2, color);
|
|
||||||
DrawLine(v1, v2, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rasterization::DrawFillTriangle(const Vector2Int v0, const Vector2Int v1, const Vector2Int v2, Color color)
|
|
||||||
{
|
|
||||||
Vector2Int aa, bb;
|
|
||||||
aa.x = std::min({ v0.x, v1.x, v2.x });
|
|
||||||
aa.y = std::min({ v0.y, v1.y, v2.y });
|
|
||||||
bb.x = std::max({ v0.x, v1.x, v2.x });
|
|
||||||
bb.y = std::max({ v0.y, v1.y, v2.y });
|
|
||||||
Triangle triangle(v0, v1, v2);
|
|
||||||
|
|
||||||
for (int x = aa.x; x <= bb.x; x++)
|
|
||||||
{
|
|
||||||
for (int y = aa.y; y <= bb.y; y++)
|
|
||||||
{
|
|
||||||
if (triangle.IsInTriangle(Vector2Int(x, y)))
|
|
||||||
{
|
|
||||||
SetPixel(Vector2Int(x, y), color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "StructType.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <cstdint>
|
|
||||||
using namespace CustomStructs;
|
|
||||||
|
|
||||||
class Rasterization
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int32_t width;
|
|
||||||
int32_t height;
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::vector<uint32_t> frameBuffer;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void DrawLineHorizontal(Vector2Int v0, Vector2Int v1, Color color);
|
|
||||||
|
|
||||||
void DrawLineVertical(Vector2Int v0, Vector2Int v1, Color color);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Rasterization(const int32_t width, const int32_t height)
|
|
||||||
: width(width), height(height), frameBuffer(std::vector<uint32_t>(static_cast<size_t>(width)* static_cast<size_t>(height))) {}
|
|
||||||
|
|
||||||
void Clear(const Color color);
|
|
||||||
|
|
||||||
void SetPixel(const Vector2Int pos, const Color color);
|
|
||||||
|
|
||||||
void DrawLine(const Vector2Int v0, const Vector2Int v1, Color color);
|
|
||||||
|
|
||||||
void DrawWireTriangle(const Vector2Int v0, const Vector2Int v1, const Vector2Int v2, Color color);
|
|
||||||
|
|
||||||
void DrawFillTriangle(const Vector2Int v0, const Vector2Int v1, const Vector2Int v2, Color color);
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
#include "Rasterizer.h"
|
||||||
|
#include <Vector2.h>
|
||||||
|
#include "Color.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Rasterizer
|
||||||
|
{
|
||||||
|
using namespace Math;
|
||||||
|
using namespace RenderData;
|
||||||
|
|
||||||
|
void Rasterizer::DrawLineHorizontal(const Vector2Int v0, const Vector2Int v1, const Color color)
|
||||||
|
{
|
||||||
|
Vector2Int start = v0, end = v1;
|
||||||
|
if (v0.x > v1.x)
|
||||||
|
{
|
||||||
|
start = v1;
|
||||||
|
end = v0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dx = end.x - start.x;
|
||||||
|
int32_t dy = end.y - start.y;
|
||||||
|
|
||||||
|
int32_t dir = dy < 0 ? -1 : 1;
|
||||||
|
dy *= dir;
|
||||||
|
|
||||||
|
if (dx == 0) return;
|
||||||
|
|
||||||
|
int32_t y = start.y;
|
||||||
|
int32_t p = 2 * dy - dx;
|
||||||
|
for (int32_t x = start.x; x <= end.x; x++)
|
||||||
|
{
|
||||||
|
frameBuffer.set_pixel(x, y, color.to_rgba());
|
||||||
|
// 当 p >= 0 时,取上方像素点
|
||||||
|
if (p >= 0)
|
||||||
|
{
|
||||||
|
y += dir;
|
||||||
|
p -= 2 * dx;
|
||||||
|
}
|
||||||
|
// 当 p < 0 时,取下方像素点
|
||||||
|
p += 2 * dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rasterizer::DrawLineVertical(const Vector2Int v0, const Vector2Int v1, const Color color)
|
||||||
|
{
|
||||||
|
Vector2Int start = v0, end = v1;
|
||||||
|
if (v0.y > v1.y)
|
||||||
|
{
|
||||||
|
start = v1;
|
||||||
|
end = v0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dx = end.x - start.x;
|
||||||
|
int32_t dy = end.y - start.y;
|
||||||
|
|
||||||
|
int32_t dir = dx < 0 ? -1 : 1;
|
||||||
|
dx *= dir;
|
||||||
|
|
||||||
|
if (dy == 0) return;
|
||||||
|
|
||||||
|
int32_t x = start.x;
|
||||||
|
int32_t p = 2 * dx - dy;
|
||||||
|
for (int32_t y = start.y; y <= end.y; y++)
|
||||||
|
{
|
||||||
|
frameBuffer.set_pixel(x, y, color.to_rgba());
|
||||||
|
// 当 p >= 0 时,取上方像素点
|
||||||
|
if (p >= 0)
|
||||||
|
{
|
||||||
|
x += dir;
|
||||||
|
p -= 2 * dy;
|
||||||
|
}
|
||||||
|
// 当 p < 0 时,取下方像素点
|
||||||
|
p += 2 * dx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在给定的起始点和结束点之间绘制一条线段,并使用指定的颜色填充
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v0">直线顶点 1</param>
|
||||||
|
/// <param name="v1">直线顶点 2</param>
|
||||||
|
/// <param name="color">绘制的颜色</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// bresenham 画线算法
|
||||||
|
/// </remarks>
|
||||||
|
void Rasterizer::DrawLine(const Vector2Int v0, const Vector2Int v1, const Color color)
|
||||||
|
{
|
||||||
|
int32_t x0 = v0.x, y0 = v0.y;
|
||||||
|
int32_t x1 = v1.x, y1 = v1.y;
|
||||||
|
|
||||||
|
if (std::abs(x1 - x0) > std::abs(y1 - y0))
|
||||||
|
{
|
||||||
|
DrawLineHorizontal(v0, v1, color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawLineVertical(v0, v1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Color.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include <Vector2.h>
|
||||||
|
|
||||||
|
namespace Rasterizer
|
||||||
|
{
|
||||||
|
class Rasterizer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Core::FrameBuffer& frameBuffer;
|
||||||
|
|
||||||
|
void DrawLineHorizontal(const Math::Vector2Int v0, const Math::Vector2Int v1, const RenderData::Color color);
|
||||||
|
void DrawLineVertical(const Math::Vector2Int v0, const Math::Vector2Int v1, const RenderData::Color color);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Rasterizer(Core::FrameBuffer& frameBuffer) :frameBuffer(frameBuffer) {};
|
||||||
|
|
||||||
|
void DrawLine(const Math::Vector2Int v0, const Math::Vector2Int v1, const RenderData::Color color);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "TriangleRasterizer.h"
|
||||||
|
#include <Triangle.h>
|
||||||
|
#include <Color.h>
|
||||||
|
#include "BoundingBox.h"
|
||||||
|
#include <Vector2.h>
|
||||||
|
using namespace RenderData;
|
||||||
|
|
||||||
|
namespace Rasterizer
|
||||||
|
{
|
||||||
|
void TriangleRasterizer::DrawTriangle2D(const Triangle2D triangle, const Color color)
|
||||||
|
{
|
||||||
|
auto boundingBox = triangle.get_boundingBox();
|
||||||
|
|
||||||
|
for (int x = boundingBox.min.x; x <= boundingBox.max.x; x++)
|
||||||
|
{
|
||||||
|
for (int y = boundingBox.min.y; y <= boundingBox.max.y; y++)
|
||||||
|
{
|
||||||
|
if (triangle.ContainsPixel(Vector2(x, y)))
|
||||||
|
{
|
||||||
|
frameBuffer.set_pixel(Vector2Int(x, y), color.to_rgba());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Triangle.h"
|
||||||
|
#include "Color.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
|
||||||
|
namespace Rasterizer
|
||||||
|
{
|
||||||
|
class TriangleRasterizer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Core::FrameBuffer& frameBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TriangleRasterizer(Core::FrameBuffer& frameBuffer) :frameBuffer(frameBuffer) {};
|
||||||
|
|
||||||
|
void DrawTriangle2D(const RenderData::Triangle2D triangle, const RenderData::Color color);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Vector2.h"
|
||||||
|
|
||||||
|
namespace RenderData
|
||||||
|
{
|
||||||
|
struct BoundingBox2D
|
||||||
|
{
|
||||||
|
Math::Vector2 min;
|
||||||
|
Math::Vector2 max;
|
||||||
|
|
||||||
|
BoundingBox2D() : min(), max() {}
|
||||||
|
BoundingBox2D(const Math::Vector2 min, const Math::Vector2 max) : min(min), max(max) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace RenderData
|
||||||
|
{
|
||||||
|
struct Color
|
||||||
|
{
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t a;
|
||||||
|
Color() : r(0), g(0), b(0), a(0) {}
|
||||||
|
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
|
{
|
||||||
|
this->r = ClampToByte(r);
|
||||||
|
this->g = ClampToByte(g);
|
||||||
|
this->b = ClampToByte(b);
|
||||||
|
this->a = ClampToByte(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t to_rgba() const
|
||||||
|
{
|
||||||
|
uint32_t value = (static_cast<uint32_t>(r) << 24) | (static_cast<uint32_t>(g) << 16) | (static_cast<uint32_t>(b) << 8) | (static_cast<uint32_t>(a));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t ClampToByte(const int32_t value)
|
||||||
|
{
|
||||||
|
if (value < 0) return 0;
|
||||||
|
if (value > 255) return 255;
|
||||||
|
return static_cast<uint8_t>(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Vector2.h"
|
||||||
|
#include "BoundingBox.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace RenderData
|
||||||
|
{
|
||||||
|
using namespace Math;
|
||||||
|
struct Triangle2D
|
||||||
|
{
|
||||||
|
Vector2 v0;
|
||||||
|
Vector2 v1;
|
||||||
|
Vector2 v2;
|
||||||
|
Triangle2D() : v0(), v1(), v2() {}
|
||||||
|
Triangle2D(const Vector2 a, const Vector2 b, const Vector2 c) : v0(a), v1(b), v2(c) {}
|
||||||
|
|
||||||
|
BoundingBox2D get_boundingBox() const
|
||||||
|
{
|
||||||
|
Vector2 min, max;
|
||||||
|
min = Vector2(std::min({ v0.x, v1.x, v2.x }), min.y = std::min({ v0.y, v1.y, v2.y }));
|
||||||
|
max = Vector2(std::max({ v0.x, v1.x, v2.x }), max.y = std::max({ v0.y, v1.y, v2.y }));
|
||||||
|
|
||||||
|
return BoundingBox2D(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContainsPixel(const Vector2 point) const
|
||||||
|
{
|
||||||
|
auto cross = [](const Vector2& p1, const Vector2& p2, const Vector2& p3) -> float
|
||||||
|
{
|
||||||
|
const float x1 = p2.x - p1.x;
|
||||||
|
const float y1 = p2.y - p1.y;
|
||||||
|
const float x2 = p3.x - p1.x;
|
||||||
|
const float y2 = p3.y - p1.y;
|
||||||
|
return x1 * y2 - y1 * x2;
|
||||||
|
};
|
||||||
|
|
||||||
|
const float c0 = cross(v0, v1, point);
|
||||||
|
const float c1 = cross(v1, v2, point);
|
||||||
|
const float c2 = cross(v2, v0, point);
|
||||||
|
|
||||||
|
const bool hasNeg = (c0 < 0) || (c1 < 0) || (c2 < 0);
|
||||||
|
const bool hasPos = (c0 > 0) || (c1 > 0) || (c2 > 0);
|
||||||
|
|
||||||
|
return !(hasNeg && hasPos);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Scene
|
||||||
|
{
|
||||||
|
class Camera
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Scene
|
||||||
|
{
|
||||||
|
class Mesh
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Scene
|
||||||
|
{
|
||||||
|
class Model
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Scene
|
||||||
|
{
|
||||||
|
class Transform
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Scene
|
||||||
|
{
|
||||||
|
class Vertex
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Shading
|
||||||
|
{
|
||||||
|
class BlinnPhongShader
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Shading
|
||||||
|
{
|
||||||
|
enum class ShaderType
|
||||||
|
{
|
||||||
|
BlinnPhong,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,142 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace CustomStructs
|
|
||||||
{
|
|
||||||
struct Vector2Int
|
|
||||||
{
|
|
||||||
int32_t x;
|
|
||||||
int32_t y;
|
|
||||||
Vector2Int() : x(0), y(0) {}
|
|
||||||
Vector2Int(int32_t x, int32_t y) : x(x), y(y) {}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 交换 x 和 y 的值
|
|
||||||
/// </summary>
|
|
||||||
void swap()
|
|
||||||
{
|
|
||||||
std::swap(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 交换当前 Vector2Int 对象与另一个 Vector2Int 对象的 x 和 y 的值
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">要交换的对象</param>
|
|
||||||
static void swap(Vector2Int& vec1, Vector2Int& vec2)
|
|
||||||
{
|
|
||||||
std::swap(vec1.x, vec2.x);
|
|
||||||
std::swap(vec1.y, vec2.y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vector2
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
Vector2() : x(0), y(0) {}
|
|
||||||
Vector2(float x, float y) : x(x), y(y) {}
|
|
||||||
Vector2(const Vector2Int& v) : x(static_cast<float>(v.x)), y(static_cast<float>(v.y)) {}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 交换 x 和 y 的值
|
|
||||||
/// </summary>
|
|
||||||
void swap()
|
|
||||||
{
|
|
||||||
std::swap(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 交换当前 Vector2 对象与另一个 Vector2 对象的 x 和 y 的值
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="other">要交换的对象</param>
|
|
||||||
static void swap(Vector2& vec1, Vector2& vec2)
|
|
||||||
{
|
|
||||||
std::swap(vec1.x, vec2.x);
|
|
||||||
std::swap(vec1.y, vec2.y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vector3Int
|
|
||||||
{
|
|
||||||
int32_t x;
|
|
||||||
int32_t y;
|
|
||||||
int32_t z;
|
|
||||||
Vector3Int() : x(0), y(0), z(0) {}
|
|
||||||
Vector3Int(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vector3
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
Vector3() : x(0), y(0), z(0) {}
|
|
||||||
Vector3(float x, float y, float z) : x(x), y(y), z(z) {}
|
|
||||||
Vector3(const Vector3Int& v) : x(static_cast<float>(v.x)), y(static_cast<float>(v.y)), z(static_cast<float>(v.z)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Triangle
|
|
||||||
{
|
|
||||||
Vector2Int a;
|
|
||||||
Vector2Int b;
|
|
||||||
Vector2Int c;
|
|
||||||
Triangle() : a(), b(), c() {}
|
|
||||||
Triangle(const Vector2Int a, const Vector2Int b, const Vector2Int c) : a(a), b(b), c(c) {}
|
|
||||||
|
|
||||||
bool IsInTriangle(const Vector2Int point) const
|
|
||||||
{
|
|
||||||
auto cross = [](const Vector2Int& p1, const Vector2Int& p2, const Vector2Int& p3) -> int64_t
|
|
||||||
{
|
|
||||||
const int64_t x1 = static_cast<int64_t>(p2.x) - p1.x;
|
|
||||||
const int64_t y1 = static_cast<int64_t>(p2.y) - p1.y;
|
|
||||||
const int64_t x2 = static_cast<int64_t>(p3.x) - p1.x;
|
|
||||||
const int64_t y2 = static_cast<int64_t>(p3.y) - p1.y;
|
|
||||||
return x1 * y2 - y1 * x2;
|
|
||||||
};
|
|
||||||
|
|
||||||
const int64_t c0 = cross(a, b, point);
|
|
||||||
const int64_t c1 = cross(b, c, point);
|
|
||||||
const int64_t c2 = cross(c, a, point);
|
|
||||||
|
|
||||||
const bool hasNeg = (c0 < 0) || (c1 < 0) || (c2 < 0);
|
|
||||||
const bool hasPos = (c0 > 0) || (c1 > 0) || (c2 > 0);
|
|
||||||
|
|
||||||
return !(hasNeg && hasPos);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Color
|
|
||||||
{
|
|
||||||
uint8_t r;
|
|
||||||
uint8_t g;
|
|
||||||
uint8_t b;
|
|
||||||
uint8_t a;
|
|
||||||
Color() : r(0), g(0), b(0), a(0) {}
|
|
||||||
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
|
||||||
{
|
|
||||||
this->r = ClampToByte(static_cast<int32_t>(r));
|
|
||||||
this->g = ClampToByte(static_cast<int32_t>(g));
|
|
||||||
this->b = ClampToByte(static_cast<int32_t>(b));
|
|
||||||
this->a = ClampToByte(static_cast<int32_t>(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
operator uint32_t() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(
|
|
||||||
(static_cast<uint32_t>(r) << 24) |
|
|
||||||
(static_cast<uint32_t>(g) << 16) |
|
|
||||||
(static_cast<uint32_t>(b) << 8) |
|
|
||||||
(static_cast<uint32_t>(a))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t ClampToByte(const int32_t value)
|
|
||||||
{
|
|
||||||
if (value < 0) return 0;
|
|
||||||
if (value > 255) return 255;
|
|
||||||
return static_cast<uint8_t>(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
#include <vector>
|
#include <iostream>
|
||||||
#include <iostream>
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include "Rasterization.h"
|
|
||||||
#include "StructType.h"
|
|
||||||
#include "SDL_video.h"
|
#include "SDL_video.h"
|
||||||
#include "SDL_render.h"
|
#include "SDL_render.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
#include <cmath>
|
#include "Vector2.h"
|
||||||
|
#include "Color.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "Rasterizer.h"
|
||||||
|
|
||||||
const uint32_t SDL_INIT_FLAGS = SDL_INIT_VIDEO;
|
const uint32_t SDL_INIT_FLAGS = SDL_INIT_VIDEO;
|
||||||
const int width = 800;
|
const int32_t width = 800;
|
||||||
const int height = 600;
|
const int32_t height = 600;
|
||||||
SDL_Window* window = nullptr;
|
SDL_Window* window = nullptr;
|
||||||
SDL_Renderer* renderer = nullptr;
|
SDL_Renderer* renderer = nullptr;
|
||||||
|
|
||||||
|
|
@ -90,20 +90,25 @@ int main(int argc, char* argv[])
|
||||||
if (!EnsureSDLWindow()) return -1;
|
if (!EnsureSDLWindow()) return -1;
|
||||||
|
|
||||||
if (!EnsureRenderer()) return -1;
|
if (!EnsureRenderer()) return -1;
|
||||||
|
|
||||||
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||||
|
|
||||||
Rasterization* rasterization = new Rasterization(width, height);
|
Core::FrameBuffer frameBuffer(width, height);
|
||||||
|
Rasterizer::Rasterizer rasterizer(frameBuffer);
|
||||||
|
|
||||||
CustomStructs::Vector2Int v0(100, 100);
|
Math::Vector2Int v0(100, 100);
|
||||||
CustomStructs::Vector2Int v1(300, 100);
|
Math::Vector2Int v1(300, 100);
|
||||||
CustomStructs::Vector2Int v2(300, 400);
|
Math::Vector2Int v2(300, 400);
|
||||||
CustomStructs::Color color1(255, 0, 0, 255);
|
RenderData::Color color0(255, 0, 0, 255);
|
||||||
rasterization->DrawFillTriangle(v0, v1, v2, color1);
|
RenderData::Color color1(0, 255, 0, 255);
|
||||||
|
RenderData::Color color2(0, 0, 255, 255);
|
||||||
|
rasterizer.DrawLine(v0, v1, color0);
|
||||||
|
rasterizer.DrawLine(v1, v2, color1);
|
||||||
|
rasterizer.DrawLine(v2, v0, color2);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
SDL_UpdateTexture(texture, nullptr, rasterization->frameBuffer.data(), width * sizeof(uint32_t));
|
SDL_UpdateTexture(texture, nullptr, frameBuffer.get_buffer(), width * sizeof(uint32_t));
|
||||||
|
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
|
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
|
||||||
|
|
|
||||||
247
README.md
247
README.md
|
|
@ -1,158 +1,161 @@
|
||||||
# CPU Software Renderer
|
# CPU Software Renderer
|
||||||
|
|
||||||
一个基于 C++ 和 SDL2 的小型 CPU 渲染器练习项目。当前版本聚焦在最基础的 2D 光栅化能力上,通过 CPU 维护帧缓冲区,再将像素数据上传到 SDL 纹理并显示到窗口中。
|
一个基于 C++20 和 SDL2 的 CPU 软光栅化练习项目。
|
||||||
|
|
||||||
项目目标不是调用现成图形 API 去画三角形,而是从像素写入、直线绘制、三角形光栅化开始,逐步补齐一个软件渲染器所需的核心 pipeline。
|
这个仓库当前还处在早期阶段,重点不是调用现成图形 API 画三角形,而是自己维护帧缓冲、自己做基础光栅化,并逐步搭起一个小型 software renderer 的骨架。
|
||||||
|
|
||||||
## 项目定位
|
|
||||||
|
|
||||||
- 使用 CPU 完成像素级绘制和光栅化
|
|
||||||
- 使用 SDL2 负责窗口创建、纹理更新和屏幕展示
|
|
||||||
- 以最小可运行工程为基础,逐步扩展到 3D 渲染流程
|
|
||||||
|
|
||||||
## 当前状态
|
## 当前状态
|
||||||
|
|
||||||
当前代码已经具备这些基础能力:
|
目前已经完成或具备雏形的部分:
|
||||||
|
|
||||||
- 基于 `frameBuffer` 的软件像素输出
|
- 使用 SDL2 创建窗口、纹理和显示循环
|
||||||
- `SetPixel` 像素写入
|
- 在 CPU 侧维护 `FrameBuffer`
|
||||||
- Bresenham 直线绘制
|
- 像素写入接口 `set_pixel`
|
||||||
- 三角形线框绘制
|
- 基础直线光栅化模块 `Rasterizer`
|
||||||
- 三角形包围盒扫描填充
|
- 2D 三角形、包围盒、颜色等基础数据结构
|
||||||
- SDL2 窗口创建、纹理更新与显示
|
- 独立的 `TriangleRasterizer` 模块,用于后续填充三角形
|
||||||
|
|
||||||
当前 `main.cpp` 中已经可以直接绘制一个填充三角形,用来验证基础光栅化逻辑。
|
当前 `main.cpp` 主要用于验证基础链路,程序启动后会在窗口中绘制三条彩色线段组成的三角形轮廓。
|
||||||
|
|
||||||
## 技术选型
|
还没有完成的核心能力:
|
||||||
|
|
||||||
- 语言标准:C++20
|
- 完整接入实心三角形渲染流程
|
||||||
- 工程类型:Visual Studio C++ 项目(`.vcxproj`)
|
- MVP 变换
|
||||||
- 渲染方式:CPU Software Rasterization
|
- 深度测试
|
||||||
- 窗口与展示层:SDL2
|
- 重心坐标插值
|
||||||
- 开发环境:Windows + MSVC
|
- 光照
|
||||||
|
- OBJ 加载
|
||||||
|
- 可交互相机
|
||||||
|
|
||||||
选择 SDL2 的原因很直接:它只负责跨平台窗口和像素展示,足够轻量,不会替代掉软件渲染器本身的核心逻辑。
|
## 当前结构
|
||||||
|
|
||||||
## 依赖
|
|
||||||
|
|
||||||
项目当前依赖很少:
|
|
||||||
|
|
||||||
- SDL2
|
|
||||||
|
|
||||||
仓库内已经包含 SDL2 相关文件:
|
|
||||||
|
|
||||||
- 头文件目录:`libs/SDL2/include`
|
|
||||||
- x64 库目录:`libs/SDL2/lib/x64`
|
|
||||||
- 运行时动态库:`libs/SDL2/SDL2.dll`
|
|
||||||
|
|
||||||
## 构建环境
|
|
||||||
|
|
||||||
当前工程配置以 Windows 本地开发为主,推荐环境:
|
|
||||||
|
|
||||||
- Visual Studio 2022
|
|
||||||
- MSVC 工具链
|
|
||||||
- Windows 10/11 SDK
|
|
||||||
|
|
||||||
项目文件中启用了:
|
|
||||||
|
|
||||||
- `stdcpp20`
|
|
||||||
- `PlatformToolset=v145`
|
|
||||||
|
|
||||||
## 构建方式
|
|
||||||
|
|
||||||
1. 使用 Visual Studio 打开 `CPU-Software-Renderer.vcxproj`
|
|
||||||
2. 选择 `Debug | x64`
|
|
||||||
3. 直接构建并运行
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 当前工程的 SDL2 include/lib 路径写在 `.vcxproj` 里
|
|
||||||
- 现有配置里 `Debug | x64` 已配置 SDL2 头文件和链接目录
|
|
||||||
- 如果你移动了仓库位置,可能需要同步调整工程中的绝对路径
|
|
||||||
|
|
||||||
## 当前工程结构
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
CPU-Software-Renderer/
|
CPU-Software-Renderer/
|
||||||
├─ main.cpp # 程序入口,SDL 初始化与显示循环
|
├─ CPU-Software-Renderer/
|
||||||
├─ Rasterization.h/.cpp # 帧缓冲、画线、三角形绘制
|
│ ├─ main.cpp
|
||||||
├─ StructType.h # 向量、三角形、颜色等基础结构
|
│ ├─ Core/
|
||||||
├─ Color.h/.cpp # 颜色相关封装
|
│ │ ├─ FrameBuffer.h/.cpp
|
||||||
├─ libs/SDL2/ # SDL2 头文件、库和运行时文件
|
│ │ ├─ DepthBuffer.h/.cpp
|
||||||
└─ TODO.md # 后续功能路线图
|
│ │ └─ Renderer.h/.cpp
|
||||||
|
│ ├─ Math/
|
||||||
|
│ │ ├─ Vector2.h
|
||||||
|
│ │ ├─ Vector3.h
|
||||||
|
│ │ ├─ Vector4.h
|
||||||
|
│ │ ├─ Matrix4x4.h
|
||||||
|
│ │ └─ MathUtil.h
|
||||||
|
│ ├─ RenderData/
|
||||||
|
│ │ ├─ Color.h
|
||||||
|
│ │ ├─ BoundingBox.h
|
||||||
|
│ │ └─ Triangle.h
|
||||||
|
│ ├─ Rasterizer/
|
||||||
|
│ │ ├─ Rasterizer.h/.cpp
|
||||||
|
│ │ └─ TriangleRasterizer.h/.cpp
|
||||||
|
│ ├─ Scene/
|
||||||
|
│ │ ├─ Vertex.h
|
||||||
|
│ │ ├─ Mesh.h
|
||||||
|
│ │ ├─ Transform.h
|
||||||
|
│ │ ├─ Model.h
|
||||||
|
│ │ └─ Camera.h
|
||||||
|
│ ├─ Asset/
|
||||||
|
│ │ └─ ObjLoader.h/.cpp
|
||||||
|
│ ├─ Shading/
|
||||||
|
│ │ ├─ ShaderTypes.h
|
||||||
|
│ │ └─ BlinnPhongShader.h/.cpp
|
||||||
|
│ ├─ libs/SDL2/
|
||||||
|
│ └─ TODO.md
|
||||||
|
└─ README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
## 已实现模块
|
## 模块说明
|
||||||
|
|
||||||
### 1. Frame Buffer
|
### Core
|
||||||
|
|
||||||
渲染结果先写入 CPU 侧的 `std::vector<uint32_t>` 帧缓冲区,再通过 `SDL_UpdateTexture` 更新到纹理。
|
- `FrameBuffer`:管理 CPU 侧颜色缓冲
|
||||||
|
- `DepthBuffer`:为后续深度测试预留
|
||||||
|
- `Renderer`:为后续统一调度渲染流程预留
|
||||||
|
|
||||||
### 2. Rasterizer
|
### Math
|
||||||
|
|
||||||
当前已经实现:
|
- 放通用数学类型
|
||||||
|
- 当前以 `Vector2`、`Vector2Int`、`Vector3` 为主
|
||||||
|
- `Vector4` 和 `Matrix4x4` 目前还是占位
|
||||||
|
|
||||||
- `DrawLine`
|
### RenderData
|
||||||
- `DrawWireTriangle`
|
|
||||||
- `DrawFillTriangle`
|
|
||||||
|
|
||||||
其中直线绘制使用 Bresenham 思路,填充三角形使用包围盒扫描配合点在三角形内测试。
|
- 放渲染领域数据,而不是底层数学类型
|
||||||
|
- 当前包含 `Color`、`BoundingBox2D`、`Triangle2D`
|
||||||
|
|
||||||
### 3. 基础数学类型
|
### Rasterizer
|
||||||
|
|
||||||
当前工程已经定义了:
|
- `Rasterizer`:负责基础线段光栅化
|
||||||
|
- `TriangleRasterizer`:负责三角形填充相关逻辑
|
||||||
|
|
||||||
- `Vector2Int`
|
### Scene / Asset / Shading
|
||||||
- `Vector2`
|
|
||||||
- `Vector3Int`
|
|
||||||
- `Vector3`
|
|
||||||
- `Triangle`
|
|
||||||
- `Color`
|
|
||||||
|
|
||||||
这些结构会作为后续扩展 MVP 变换、深度测试、法线和属性插值的基础。
|
这些目录已经预留出来了,方便后面扩展到 3D 渲染流程,但当前多数还是占位类。
|
||||||
|
|
||||||
|
## 构建环境
|
||||||
|
|
||||||
|
- Windows
|
||||||
|
- Visual Studio 2022
|
||||||
|
- MSVC
|
||||||
|
- C++20
|
||||||
|
- SDL2
|
||||||
|
|
||||||
|
工程文件是 Visual Studio 的 `.vcxproj`。
|
||||||
|
|
||||||
|
## 依赖
|
||||||
|
|
||||||
|
仓库内已经包含 SDL2:
|
||||||
|
|
||||||
|
- 头文件:`CPU-Software-Renderer/libs/SDL2/include`
|
||||||
|
- Win32 库:`CPU-Software-Renderer/libs/SDL2/lib/x86`
|
||||||
|
- x64 库:`CPU-Software-Renderer/libs/SDL2/lib/x64`
|
||||||
|
|
||||||
|
## 构建与运行
|
||||||
|
|
||||||
|
1. 用 Visual Studio 打开 `CPU-Software-Renderer/CPU-Software-Renderer.vcxproj`
|
||||||
|
2. 选择 `Debug` 或 `Release`
|
||||||
|
3. 选择 `Win32` 或 `x64`
|
||||||
|
4. 构建并运行
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 工程里已经分别配置了 Win32 和 x64 的 SDL2 include/lib 路径
|
||||||
|
- 运行时需要让程序找到与平台匹配的 `SDL2.dll`
|
||||||
|
- 如果你移动了仓库位置,可能需要同步检查 `.vcxproj` 里的绝对路径
|
||||||
|
|
||||||
|
## 设计取向
|
||||||
|
|
||||||
|
当前代码结构遵循一个比较简单的原则:
|
||||||
|
|
||||||
|
- 纯数据类型放在 `Math` 和 `RenderData`
|
||||||
|
- 做事的模块放在 `Core`、`Rasterizer`、`Asset`、`Shading`
|
||||||
|
- 先把 2D 基础链路理顺,再逐步加 3D pipeline
|
||||||
|
|
||||||
|
这意味着现阶段更强调“结构和边界先理清”,而不是一次性把所有功能堆进去。
|
||||||
|
|
||||||
## 后续计划
|
## 后续计划
|
||||||
|
|
||||||
1. 完成稳定的三角形光栅化基础
|
按 `TODO.md` 的路线,后续会逐步补齐:
|
||||||
2. 加入 MVP 变换,实现 3D 顶点到屏幕空间的投影
|
|
||||||
3. 加入 Z-buffer,解决遮挡关系
|
|
||||||
4. 实现重心坐标属性插值
|
|
||||||
5. 实现 Blinn-Phong 光照
|
|
||||||
6. 支持 OBJ 模型加载
|
|
||||||
7. 实现相机控制
|
|
||||||
|
|
||||||
如果后续继续扩展,比较值得加入的方向还有:
|
1. 稳定的三角形填充
|
||||||
|
2. MVP 变换
|
||||||
|
3. Z-buffer
|
||||||
|
4. 属性插值
|
||||||
|
5. Blinn-Phong 光照
|
||||||
|
6. OBJ 模型加载
|
||||||
|
7. 相机控制
|
||||||
|
|
||||||
|
如果后续继续扩展,还可以考虑:
|
||||||
|
|
||||||
- Texture Mapping
|
- Texture Mapping
|
||||||
- MSAA 抗锯齿
|
- MSAA
|
||||||
- 更完整的数学库
|
- 更完整的数学库
|
||||||
- Shader 结构拆分
|
- 更清晰的 shader 输入输出结构
|
||||||
|
|
||||||
## 这个项目最终会变成什么
|
|
||||||
|
|
||||||
按当前路线推进后,这个项目会逐步具备一个小型软件渲染器的基本结构:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Renderer
|
|
||||||
├─ Rasterizer
|
|
||||||
├─ Shader
|
|
||||||
├─ Camera
|
|
||||||
├─ Math
|
|
||||||
├─ OBJLoader
|
|
||||||
└─ ZBuffer
|
|
||||||
```
|
|
||||||
|
|
||||||
最终目标是实现一个不依赖 GPU 光栅化管线、但具备基本 3D 渲染能力的 CPU Renderer。
|
|
||||||
|
|
||||||
## 适合用来做什么
|
|
||||||
|
|
||||||
这个项目比较适合:
|
|
||||||
|
|
||||||
- 学习软件渲染器的基本实现方式
|
|
||||||
- 理解三角形光栅化、像素写入和屏幕空间坐标
|
|
||||||
- 作为后续学习图形学、渲染 pipeline、光照和模型加载的实验场
|
|
||||||
- 用于整理个人图形学项目经历
|
|
||||||
|
|
||||||
## 说明
|
## 说明
|
||||||
|
|
||||||
当前项目仍在早期阶段,很多功能还处于逐步实现中。README 中的“后续计划”部分表示目标路线,不代表这些能力已经全部完成。
|
这个项目现在更接近“正在搭骨架的 renderer”,不是一个已经完成的 3D 渲染器。
|
||||||
|
|
||||||
|
README 中提到的很多模块和目录,目的是反映当前的架构方向;其中一部分已经有初步实现,另一部分还只是为后续阶段预留。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue