添加项目文件。
This commit is contained in:
37
Vivid2D/Vivid2D.cpp
Normal file
37
Vivid2D/Vivid2D.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Vivid2D.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||||
//
|
||||
|
||||
// 包含GLM主头文件
|
||||
#include <glm/glm.hpp>
|
||||
// 包含vec2定义
|
||||
#include <iostream>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
int main() {
|
||||
// 创建一个二维浮点向量 (Vector2f)
|
||||
glm::vec2 position(100.0f, 200.0f);
|
||||
|
||||
// 创建另一个向量代表速度
|
||||
glm::vec2 velocity(5.0f, -2.0f);
|
||||
|
||||
// 向量加法,更新位置
|
||||
position += velocity;
|
||||
|
||||
// 输出新的位置
|
||||
// GLM的向量可以直接用std::cout输出,但需要包含<glm/gtx/string_cast.hpp>
|
||||
// 这里为了简单,我们手动输出
|
||||
std::cout << "New Position: (" << position.x << ", " << position.y << ")" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
|
||||
// 调试程序: F5 或调试 >“开始调试”菜单
|
||||
|
||||
// 入门使用技巧:
|
||||
// 1. 使用解决方案资源管理器窗口添加/管理文件
|
||||
// 2. 使用团队资源管理器窗口连接到源代码管理
|
||||
// 3. 使用输出窗口查看生成输出和其他消息
|
||||
// 4. 使用错误列表窗口查看错误
|
||||
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
|
||||
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
|
||||
134
Vivid2D/Vivid2D.vcxproj
Normal file
134
Vivid2D/Vivid2D.vcxproj
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{4b88f09b-523c-4678-adcc-e1421a7dc39e}</ProjectGuid>
|
||||
<RootNamespace>Vivid2D</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vivid2D.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
22
Vivid2D/Vivid2D.vcxproj.filters
Normal file
22
Vivid2D/Vivid2D.vcxproj.filters
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<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>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vivid2D.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
44
Vivid2DRenderer.sln
Normal file
44
Vivid2DRenderer.sln
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35027.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vivid2DRenderer", "Vivid2DRenderer\Vivid2DRenderer.vcxproj", "{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vivid2D", "Vivid2D\Vivid2D.vcxproj", "{4B88F09B-523C-4678-ADCC-E1421A7DC39E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68} = {CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Debug|x64.Build.0 = Debug|x64
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Debug|x86.Build.0 = Debug|Win32
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Release|x64.ActiveCfg = Release|x64
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Release|x64.Build.0 = Release|x64
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Release|x86.ActiveCfg = Release|Win32
|
||||
{CDFA4C34-767D-49C0-AFE1-EE6C49A9DA68}.Release|x86.Build.0 = Release|Win32
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Debug|x64.Build.0 = Debug|x64
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Debug|x86.Build.0 = Debug|Win32
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Release|x64.ActiveCfg = Release|x64
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Release|x64.Build.0 = Release|x64
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Release|x86.ActiveCfg = Release|Win32
|
||||
{4B88F09B-523C-4678-ADCC-E1421A7DC39E}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {CD348B38-5FCC-4BCC-9826-2060B6862A5C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
179
Vivid2DRenderer/Vivid2DRenderer.vcxproj
Normal file
179
Vivid2DRenderer/Vivid2DRenderer.vcxproj
Normal file
@@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{cdfa4c34-767d-49c0-afe1-ee6c49a9da68}</ProjectGuid>
|
||||
<RootNamespace>Vivid2DRenderer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;VIVID2DRENDERER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;VIVID2DRENDERER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;VIVID2DRENDERER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;VIVID2DRENDERER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<DisableSpecificWarnings>4828</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="systems\buffer\BufferUploader.h" />
|
||||
<ClInclude Include="systems\buffer\BufferBuilder.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="systems\sources\def\Shader2D.h" />
|
||||
<ClInclude Include="systems\sources\def\SolidColorShader.h" />
|
||||
<ClInclude Include="systems\sources\CompleteShader.h" />
|
||||
<ClInclude Include="systems\sources\Shader.h" />
|
||||
<ClInclude Include="systems\sources\ShaderManagement.h" />
|
||||
<ClInclude Include="systems\sources\ShaderProgram.h" />
|
||||
<ClInclude Include="systems\RenderSystem.h" />
|
||||
<ClInclude Include="systems\sources\def\TextShader.h" />
|
||||
<ClInclude Include="systems\buffer\Tesselator.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="systems\buffer\BufferUploader.cpp" />
|
||||
<ClCompile Include="systems\buffer\BufferBuilder.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\sources\def\Shader2D.cpp" />
|
||||
<ClCompile Include="systems\sources\def\SolidColorShader.cpp" />
|
||||
<ClCompile Include="systems\sources\ShaderManagement.cpp" />
|
||||
<ClCompile Include="systems\sources\ShaderProgram.cpp" />
|
||||
<ClCompile Include="systems\RenderSystem.cpp" />
|
||||
<ClCompile Include="systems\sources\def\TextShader.cpp" />
|
||||
<ClCompile Include="systems\buffer\Tesselator.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
93
Vivid2DRenderer/Vivid2DRenderer.vcxproj.filters
Normal file
93
Vivid2DRenderer/Vivid2DRenderer.vcxproj.filters
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<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>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\RenderSystem.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\ShaderProgram.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\ShaderManagement.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\Shader.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\CompleteShader.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\def\TextShader.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\def\SolidColorShader.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\sources\def\Shader2D.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\buffer\Tesselator.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\buffer\BufferBuilder.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="systems\buffer\BufferUploader.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\RenderSystem.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\sources\ShaderProgram.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\sources\ShaderManagement.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\sources\def\TextShader.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\sources\def\SolidColorShader.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\sources\def\Shader2D.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\buffer\Tesselator.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\buffer\BufferBuilder.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="systems\buffer\BufferUploader.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
19
Vivid2DRenderer/dllmain.cpp
Normal file
19
Vivid2DRenderer/dllmain.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// dllmain.cpp : 定义 DLL 应用程序的入口点。
|
||||
#include "pch.h"
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
5
Vivid2DRenderer/framework.h
Normal file
5
Vivid2DRenderer/framework.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
|
||||
// Windows 头文件
|
||||
#include <windows.h>
|
||||
5
Vivid2DRenderer/pch.cpp
Normal file
5
Vivid2DRenderer/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: 与预编译标头对应的源文件
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
|
||||
13
Vivid2DRenderer/pch.h
Normal file
13
Vivid2DRenderer/pch.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// pch.h: 这是预编译标头文件。
|
||||
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
|
||||
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
|
||||
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
|
||||
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// 添加要在此处预编译的标头
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
||||
474
Vivid2DRenderer/systems/RenderSystem.cpp
Normal file
474
Vivid2DRenderer/systems/RenderSystem.cpp
Normal file
@@ -0,0 +1,474 @@
|
||||
#include "pch.h"
|
||||
#include "RenderSystem.h"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/sinks/basic_file_sink.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
// ================== <20><>̬<EFBFBD><CCAC>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC> ==================
|
||||
std::thread::id RenderSystem::s_RenderThreadId;
|
||||
std::atomic<bool> RenderSystem::s_IsInInit = false;
|
||||
std::queue<std::function<void()>> RenderSystem::s_RenderQueue;
|
||||
std::mutex RenderSystem::s_RenderQueueMutex;
|
||||
std::atomic<bool> RenderSystem::s_IsReplayingQueue = false;
|
||||
std::stack<RenderSystem::RenderState> RenderSystem::s_StateStack;
|
||||
int RenderSystem::s_ViewportWidth = 800;
|
||||
int RenderSystem::s_ViewportHeight = 600;
|
||||
glm::vec4 RenderSystem::s_ClearColorValue = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
std::shared_ptr<spdlog::logger> RenderSystem::s_Logger;
|
||||
|
||||
// ================== <20><>־ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD> ==================
|
||||
void RenderSystem::InitializeLogging() {
|
||||
std::vector<spdlog::sink_ptr> sinks;
|
||||
|
||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [thread %t] %v");
|
||||
sinks.push_back(console_sink);
|
||||
|
||||
try {
|
||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/Vivid2D.log", true);
|
||||
file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread %t] %v");
|
||||
sinks.push_back(file_sink);
|
||||
}
|
||||
catch (const spdlog::spdlog_ex& ex) {
|
||||
std::cerr << "Log file creation failed: " << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
s_Logger = std::make_shared<spdlog::logger>("RenderSystem", begin(sinks), end(sinks));
|
||||
spdlog::register_logger(s_Logger);
|
||||
s_Logger->set_level(spdlog::level::trace);
|
||||
s_Logger->flush_on(spdlog::level::trace);
|
||||
|
||||
s_Logger->info("Logging system initialized.");
|
||||
}
|
||||
|
||||
void RenderSystem::ShutdownLogging() {
|
||||
s_Logger->info("Logging system shutting down.");
|
||||
s_Logger.reset();
|
||||
spdlog::shutdown();
|
||||
}
|
||||
|
||||
// ================== <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>̹߳<DFB3><CCB9><EFBFBD> ==================
|
||||
void RenderSystem::initRenderThread() {
|
||||
if (s_RenderThreadId == std::thread::id()) {
|
||||
s_RenderThreadId = std::this_thread::get_id();
|
||||
s_Logger->info("Render thread initialized on thread ID: {}", std::hash<std::thread::id>{}(s_RenderThreadId));
|
||||
}
|
||||
else if (s_RenderThreadId != std::this_thread::get_id()) {
|
||||
s_Logger->critical("Render thread already initialized by another thread!");
|
||||
throw std::runtime_error("Render thread already initialized by another thread");
|
||||
}
|
||||
}
|
||||
void RenderSystem::beginInitialization() { s_IsInInit = true; }
|
||||
void RenderSystem::finishInitialization() {
|
||||
s_IsInInit = false;
|
||||
if (getQueueSize() > 0) { replayQueue(); }
|
||||
}
|
||||
bool RenderSystem::isOnRenderThread() { return std::this_thread::get_id() == s_RenderThreadId; }
|
||||
bool RenderSystem::isInInitPhase() { return s_IsInInit; }
|
||||
void RenderSystem::assertOnRenderThread() { if (!isOnRenderThread()) { throw std::runtime_error("RenderSystem called from wrong thread!"); } }
|
||||
void RenderSystem::assertOnRenderThreadOrInit() { if (!isInInitPhase() && !isOnRenderThread()) { throw std::runtime_error("RenderSystem called from wrong thread!"); } }
|
||||
|
||||
// ================== <20><>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
void RenderSystem::recordRenderCall(std::function<void()>&& renderCall) {
|
||||
std::lock_guard<std::mutex> lock(s_RenderQueueMutex);
|
||||
s_RenderQueue.push(std::move(renderCall));
|
||||
}
|
||||
void RenderSystem::replayQueue() {
|
||||
s_IsReplayingQueue = true;
|
||||
std::queue<std::function<void()>> localQueue;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_RenderQueueMutex);
|
||||
s_RenderQueue.swap(localQueue);
|
||||
}
|
||||
while (!localQueue.empty()) {
|
||||
auto& call = localQueue.front();
|
||||
if (call) { call(); }
|
||||
localQueue.pop();
|
||||
}
|
||||
s_IsReplayingQueue = false;
|
||||
}
|
||||
|
||||
// ================== OpenGL ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ ==================
|
||||
#define RENDER_SYSTEM_QUEUE_CALL(FunctionName, ...) \
|
||||
if (!isOnRenderThread()) { \
|
||||
recordRenderCall([=] { FunctionName(__VA_ARGS__); }); \
|
||||
} else { \
|
||||
FunctionName(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(FunctionName) \
|
||||
if (!isOnRenderThread()) { \
|
||||
recordRenderCall([=] { FunctionName(); }); \
|
||||
} else { \
|
||||
FunctionName(); \
|
||||
}
|
||||
|
||||
void RenderSystem::enable(GLenum capability) { RENDER_SYSTEM_QUEUE_CALL(_enable, capability); }
|
||||
void RenderSystem::_enable(GLenum c) { assertOnRenderThread(); glEnable(c); }
|
||||
|
||||
void RenderSystem::disable(GLenum capability) { RENDER_SYSTEM_QUEUE_CALL(_disable, capability); }
|
||||
void RenderSystem::_disable(GLenum c) { assertOnRenderThread(); glDisable(c); }
|
||||
|
||||
void RenderSystem::pushState() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_pushState); }
|
||||
void RenderSystem::_pushState() {
|
||||
assertOnRenderThread();
|
||||
_checkGLError("before pushState");
|
||||
s_StateStack.push(RenderState());
|
||||
_checkGLError("after pushState");
|
||||
}
|
||||
|
||||
void RenderSystem::popState() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_popState); }
|
||||
void RenderSystem::_popState() {
|
||||
assertOnRenderThread();
|
||||
if (!s_StateStack.empty()) {
|
||||
s_StateStack.top().restore();
|
||||
s_StateStack.pop();
|
||||
_checkGLError("after popState");
|
||||
}
|
||||
else {
|
||||
s_Logger->warn("popState called with empty state stack.");
|
||||
}
|
||||
}
|
||||
int RenderSystem::getStateStackSize() { return s_StateStack.size(); }
|
||||
|
||||
void RenderSystem::clearColor(float r, float g, float b, float a) { RENDER_SYSTEM_QUEUE_CALL(_clearColor, r, g, b, a); }
|
||||
void RenderSystem::_clearColor(float r, float g, float b, float a) {
|
||||
assertOnRenderThread();
|
||||
glClearColor(r, g, b, a);
|
||||
s_ClearColorValue = { r, g, b, a };
|
||||
}
|
||||
|
||||
void RenderSystem::clear(GLbitfield mask) { RENDER_SYSTEM_QUEUE_CALL(_clear, mask); }
|
||||
void RenderSystem::_clear(GLbitfield m) { assertOnRenderThread(); glClear(m); }
|
||||
|
||||
void RenderSystem::viewport(int x, int y, int width, int height) { RENDER_SYSTEM_QUEUE_CALL(_viewport, x, y, width, height); }
|
||||
void RenderSystem::_viewport(int x, int y, int w, int h) {
|
||||
assertOnRenderThread();
|
||||
glViewport(x, y, w, h);
|
||||
s_ViewportWidth = w;
|
||||
s_ViewportHeight = h;
|
||||
}
|
||||
|
||||
// ================== VAO / VBO / EBO <20><><EFBFBD><EFBFBD> ==================
|
||||
GLuint RenderSystem::GenVertexArrays() { assertOnRenderThread(); GLuint vao = 0; glGenVertexArrays(1, &vao); return vao; }
|
||||
void RenderSystem::DeleteVertexArrays(GLuint vao) { RENDER_SYSTEM_QUEUE_CALL(_glDeleteVertexArrays, vao); }
|
||||
void RenderSystem::_glDeleteVertexArrays(GLuint v) { assertOnRenderThread(); glDeleteVertexArrays(1, &v); }
|
||||
void RenderSystem::BindVertexArray(GLuint vao) { RENDER_SYSTEM_QUEUE_CALL(_glBindVertexArray, vao); }
|
||||
void RenderSystem::_glBindVertexArray(GLuint v) { assertOnRenderThread(); glBindVertexArray(v); }
|
||||
GLuint RenderSystem::GenBuffers() { assertOnRenderThread(); GLuint buf; glGenBuffers(1, &buf); return buf; }
|
||||
void RenderSystem::DeleteBuffers(GLuint buffer) { RENDER_SYSTEM_QUEUE_CALL(_glDeleteBuffers, buffer); }
|
||||
void RenderSystem::_glDeleteBuffers(GLuint b) { assertOnRenderThread(); glDeleteBuffers(1, &b); }
|
||||
void RenderSystem::BindBuffer(GLenum target, GLuint buffer) { RENDER_SYSTEM_QUEUE_CALL(_glBindBuffer, target, buffer); }
|
||||
void RenderSystem::_glBindBuffer(GLenum t, GLuint b) { assertOnRenderThread(); glBindBuffer(t, b); }
|
||||
void RenderSystem::BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
|
||||
assertOnRenderThread();
|
||||
glBufferData(target, size, data, usage);
|
||||
}
|
||||
|
||||
// [<5B><><EFBFBD><EFBFBD>] _glBufferData <20>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
void RenderSystem::_glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
|
||||
assertOnRenderThread();
|
||||
glBufferData(target, size, data, usage);
|
||||
}
|
||||
|
||||
// ================== Uniform <20><><EFBFBD><EFBFBD> ==================
|
||||
void RenderSystem::uniform1i(GLint location, int value) { RENDER_SYSTEM_QUEUE_CALL(_uniform1i, location, value); }
|
||||
void RenderSystem::_uniform1i(GLint l, int v) { assertOnRenderThread(); glUniform1i(l, v); }
|
||||
void RenderSystem::uniform1f(GLint location, float value) { RENDER_SYSTEM_QUEUE_CALL(_uniform1f, location, value); }
|
||||
void RenderSystem::_uniform1f(GLint l, float v) { assertOnRenderThread(); glUniform1f(l, v); }
|
||||
void RenderSystem::uniform2f(GLint location, float x, float y) { RENDER_SYSTEM_QUEUE_CALL(_uniform2f, location, x, y); }
|
||||
void RenderSystem::_uniform2f(GLint l, float x, float y) { assertOnRenderThread(); glUniform2f(l, x, y); }
|
||||
void RenderSystem::uniform3f(GLint location, float x, float y, float z) { RENDER_SYSTEM_QUEUE_CALL(_uniform3f, location, x, y, z); }
|
||||
void RenderSystem::_uniform3f(GLint l, float x, float y, float z) { assertOnRenderThread(); glUniform3f(l, x, y, z); }
|
||||
void RenderSystem::uniform4f(GLint location, float x, float y, float z, float w) { RENDER_SYSTEM_QUEUE_CALL(_uniform4f, location, x, y, z, w); }
|
||||
void RenderSystem::_uniform4f(GLint l, float x, float y, float z, float w) { assertOnRenderThread(); glUniform4f(l, x, y, z, w); }
|
||||
void RenderSystem::uniformMatrix3fv(GLint l, GLsizei c, GLboolean t, const GLfloat* v) { assertOnRenderThread(); glUniformMatrix3fv(l, c, t, v); }
|
||||
void RenderSystem::uniformMatrix4fv(GLint l, GLsizei c, GLboolean t, const GLfloat* v) { assertOnRenderThread(); glUniformMatrix4fv(l, c, t, v); }
|
||||
|
||||
// [<5B><><EFBFBD><EFBFBD>] _uniformMatrix3fv <20>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
void RenderSystem::_uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
assertOnRenderThread();
|
||||
glUniformMatrix3fv(location, count, transpose, value);
|
||||
}
|
||||
|
||||
// [<5B><><EFBFBD><EFBFBD>] _uniformMatrix4fv <20>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
void RenderSystem::_uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
assertOnRenderThread();
|
||||
glUniformMatrix4fv(location, count, transpose, value);
|
||||
}
|
||||
|
||||
void RenderSystem::uniform2f(GLint location, const glm::vec2& vec) { uniform2f(location, vec.x, vec.y); }
|
||||
void RenderSystem::uniform3f(GLint location, const glm::vec3& vec) { uniform3f(location, vec.x, vec.y, vec.z); }
|
||||
void RenderSystem::uniform4f(GLint location, const glm::vec4& vec) { uniform4f(location, vec.x, vec.y, vec.z, vec.w); }
|
||||
void RenderSystem::uniformMatrix3(GLint location, const glm::mat3& matrix, bool transpose) {
|
||||
if (!isOnRenderThread()) { recordRenderCall([=] { _uniformMatrix3fv(location, 1, transpose, glm::value_ptr(matrix)); }); }
|
||||
else { _uniformMatrix3fv(location, 1, transpose, glm::value_ptr(matrix)); }
|
||||
}
|
||||
void RenderSystem::uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose) {
|
||||
if (!isOnRenderThread()) { recordRenderCall([=] { _uniformMatrix4fv(location, 1, transpose, glm::value_ptr(matrix)); }); }
|
||||
else { _uniformMatrix4fv(location, 1, transpose, glm::value_ptr(matrix)); }
|
||||
}
|
||||
GLint RenderSystem::getUniformLocation(GLuint program, const std::string& name) { assertOnRenderThread(); return glGetUniformLocation(program, name.c_str()); }
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
void RenderSystem::lineWidth(float width) { RENDER_SYSTEM_QUEUE_CALL(_lineWidth, width); }
|
||||
void RenderSystem::_lineWidth(float w) { assertOnRenderThread(); glLineWidth(w); }
|
||||
void RenderSystem::drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices) { RENDER_SYSTEM_QUEUE_CALL(_drawElements, mode, count, type, indices); }
|
||||
void RenderSystem::_drawElements(GLenum m, GLsizei c, GLenum t, const void* i) { assertOnRenderThread(); glDrawElements(m, c, t, i); }
|
||||
void RenderSystem::drawArrays(GLenum mode, GLint first, GLsizei count) { RENDER_SYSTEM_QUEUE_CALL(_drawArrays, mode, first, count); }
|
||||
void RenderSystem::_drawArrays(GLenum m, GLint f, GLsizei c) { assertOnRenderThread(); glDrawArrays(m, f, c); }
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD>ģʽ ==================
|
||||
void RenderSystem::enableBlend() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_enableBlend); }
|
||||
void RenderSystem::_enableBlend() { assertOnRenderThread(); glEnable(GL_BLEND); }
|
||||
void RenderSystem::disableBlend() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_disableBlend); }
|
||||
void RenderSystem::_disableBlend() { assertOnRenderThread(); glDisable(GL_BLEND); }
|
||||
void RenderSystem::blendFunc(GLenum sfactor, GLenum dfactor) { RENDER_SYSTEM_QUEUE_CALL(_blendFunc, sfactor, dfactor); }
|
||||
void RenderSystem::_blendFunc(GLenum s, GLenum d) { assertOnRenderThread(); glBlendFunc(s, d); }
|
||||
void RenderSystem::defaultBlendFunc() { blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
|
||||
|
||||
// ================== <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
GLuint RenderSystem::createProgram() { assertOnRenderThread(); return glCreateProgram(); }
|
||||
GLint RenderSystem::getCurrentProgram() { assertOnRenderThread(); GLint p; glGetIntegerv(GL_CURRENT_PROGRAM, &p); return p; }
|
||||
void RenderSystem::attachShader(GLuint p, GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_attachShader, p, s); }
|
||||
void RenderSystem::_attachShader(GLuint p, GLuint s) { assertOnRenderThread(); glAttachShader(p, s); }
|
||||
void RenderSystem::linkProgram(GLuint p) { RENDER_SYSTEM_QUEUE_CALL(_linkProgram, p); }
|
||||
void RenderSystem::_linkProgram(GLuint p) { assertOnRenderThread(); glLinkProgram(p); }
|
||||
GLint RenderSystem::getProgrami(GLuint p, GLenum n) { assertOnRenderThread(); GLint i; glGetProgramiv(p, n, &i); return i; }
|
||||
std::string RenderSystem::getProgramInfoLog(GLuint program) {
|
||||
assertOnRenderThread();
|
||||
GLint len = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
|
||||
if (len > 1) {
|
||||
std::vector<char> log(len);
|
||||
glGetProgramInfoLog(program, len, nullptr, log.data());
|
||||
return std::string(log.begin(), log.end());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
void RenderSystem::detachShader(GLuint p, GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_detachShader, p, s); }
|
||||
void RenderSystem::_detachShader(GLuint p, GLuint s) { assertOnRenderThread(); glDetachShader(p, s); }
|
||||
void RenderSystem::deleteProgram(GLuint p) { RENDER_SYSTEM_QUEUE_CALL(_deleteProgram, p); }
|
||||
void RenderSystem::_deleteProgram(GLuint p) { assertOnRenderThread(); glDeleteProgram(p); }
|
||||
GLuint RenderSystem::linkProgram(GLuint vertexShader, GLuint fragmentShader) {
|
||||
assertOnRenderThread();
|
||||
GLuint program = createProgram();
|
||||
_attachShader(program, vertexShader);
|
||||
_attachShader(program, fragmentShader);
|
||||
_linkProgram(program);
|
||||
if (getProgrami(program, GL_LINK_STATUS) != GL_TRUE) {
|
||||
std::string log = getProgramInfoLog(program);
|
||||
s_Logger->error("Program link failed: {}", log);
|
||||
_deleteProgram(program);
|
||||
throw std::runtime_error("Program link failed: " + log);
|
||||
}
|
||||
_detachShader(program, vertexShader);
|
||||
_detachShader(program, fragmentShader);
|
||||
return program;
|
||||
}
|
||||
GLuint RenderSystem::linkProgram(GLuint v, GLuint g, GLuint f) {
|
||||
assertOnRenderThread();
|
||||
GLuint p = createProgram();
|
||||
_attachShader(p, v);
|
||||
if (g != 0) _attachShader(p, g);
|
||||
_attachShader(p, f);
|
||||
_linkProgram(p);
|
||||
if (getProgrami(p, GL_LINK_STATUS) != GL_TRUE) {
|
||||
std::string log = getProgramInfoLog(p);
|
||||
s_Logger->error("Program link failed: {}", log);
|
||||
_deleteProgram(p);
|
||||
throw std::runtime_error("Program link failed: " + log);
|
||||
}
|
||||
_detachShader(p, v);
|
||||
if (g != 0) _detachShader(p, g);
|
||||
_detachShader(p, f);
|
||||
return p;
|
||||
}
|
||||
void RenderSystem::useProgram(GLuint p) { RENDER_SYSTEM_QUEUE_CALL(_useProgram, p); }
|
||||
void RenderSystem::_useProgram(GLuint p) { assertOnRenderThread(); glUseProgram(p); }
|
||||
|
||||
// ================== <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
GLuint RenderSystem::createShader(GLenum type) { assertOnRenderThread(); return glCreateShader(type); }
|
||||
void RenderSystem::shaderSource(GLuint shader, const std::string& source) {
|
||||
if (!isOnRenderThread()) { recordRenderCall([=] { _shaderSource(shader, source); }); }
|
||||
else { _shaderSource(shader, source); }
|
||||
}
|
||||
void RenderSystem::_shaderSource(GLuint s, const std::string& src) {
|
||||
assertOnRenderThread();
|
||||
const char* c_str = src.c_str();
|
||||
glShaderSource(s, 1, &c_str, nullptr);
|
||||
}
|
||||
void RenderSystem::compileShader(GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_compileShader, s); }
|
||||
void RenderSystem::_compileShader(GLuint s) { assertOnRenderThread(); glCompileShader(s); }
|
||||
GLint RenderSystem::getShaderi(GLuint s, GLenum p) { assertOnRenderThread(); GLint i; glGetShaderiv(s, p, &i); return i; }
|
||||
std::string RenderSystem::getShaderInfoLog(GLuint shader) {
|
||||
assertOnRenderThread();
|
||||
GLint len = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
if (len > 1) {
|
||||
std::vector<char> log(len);
|
||||
glGetShaderInfoLog(shader, len, nullptr, log.data());
|
||||
return std::string(log.begin(), log.end());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
void RenderSystem::deleteShader(GLuint s) { RENDER_SYSTEM_QUEUE_CALL(_deleteShader, s); }
|
||||
void RenderSystem::_deleteShader(GLuint s) { assertOnRenderThread(); glDeleteShader(s); }
|
||||
GLuint RenderSystem::compileShader(GLenum type, const std::string& source) {
|
||||
assertOnRenderThread();
|
||||
GLuint shader = createShader(type);
|
||||
_shaderSource(shader, source);
|
||||
_compileShader(shader);
|
||||
if (getShaderi(shader, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
std::string log = getShaderInfoLog(shader);
|
||||
s_Logger->error("Shader compilation failed: {}", log);
|
||||
_deleteShader(shader);
|
||||
throw std::runtime_error("Shader compilation failed: " + log);
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
// ================== <20><><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD> ==================
|
||||
void RenderSystem::depthFunc(GLenum func) { RENDER_SYSTEM_QUEUE_CALL(_depthFunc, func); }
|
||||
void RenderSystem::_depthFunc(GLenum f) { assertOnRenderThread(); glDepthFunc(f); }
|
||||
void RenderSystem::depthMask(bool flag) { RENDER_SYSTEM_QUEUE_CALL(_depthMask, flag); }
|
||||
void RenderSystem::_depthMask(bool f) { assertOnRenderThread(); glDepthMask(f ? GL_TRUE : GL_FALSE); }
|
||||
void RenderSystem::clearDepth(double depth) { RENDER_SYSTEM_QUEUE_CALL(_clearDepth, depth); }
|
||||
void RenderSystem::_clearDepth(double d) { assertOnRenderThread(); glClearDepth(d); }
|
||||
void RenderSystem::enableDepthTest() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_enableDepthTest); }
|
||||
void RenderSystem::_enableDepthTest() { assertOnRenderThread(); glEnable(GL_DEPTH_TEST); }
|
||||
void RenderSystem::disableDepthTest() { RENDER_SYSTEM_QUEUE_CALL_NO_ARGS(_disableDepthTest); }
|
||||
void RenderSystem::_disableDepthTest() { assertOnRenderThread(); glDisable(GL_DEPTH_TEST); }
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
void RenderSystem::bindTexture(GLuint texture) { RENDER_SYSTEM_QUEUE_CALL(_bindTexture, texture); }
|
||||
void RenderSystem::_bindTexture(GLuint t) { assertOnRenderThread(); glBindTexture(GL_TEXTURE_2D, t); }
|
||||
void RenderSystem::getTexImage(GLenum t, GLint l, GLenum f, GLenum ty, void* p) { assertOnRenderThread(); glGetTexImage(t, l, f, ty, p); }
|
||||
|
||||
// [<5B><><EFBFBD><EFBFBD>] _getTexImage <20>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
void RenderSystem::_getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) {
|
||||
assertOnRenderThread();
|
||||
glGetTexImage(target, level, format, type, pixels);
|
||||
}
|
||||
|
||||
void RenderSystem::activeTexture(GLenum texture) { RENDER_SYSTEM_QUEUE_CALL(_activeTexture, texture); }
|
||||
void RenderSystem::_activeTexture(GLenum t) { assertOnRenderThread(); glActiveTexture(t); }
|
||||
GLuint RenderSystem::genTextures() { assertOnRenderThread(); GLuint t; glGenTextures(1, &t); return t; }
|
||||
void RenderSystem::deleteTextures(GLuint texture) { RENDER_SYSTEM_QUEUE_CALL(_deleteTextures, texture); }
|
||||
void RenderSystem::_deleteTextures(GLuint t) { assertOnRenderThread(); glDeleteTextures(1, &t); }
|
||||
void RenderSystem::texImage2D(GLenum t, GLint l, GLint iF, GLsizei w, GLsizei h, GLint b, GLenum f, GLenum ty, const void* p) { assertOnRenderThread(); glTexImage2D(t, l, iF, w, h, b, f, ty, p); }
|
||||
|
||||
// [<5B><><EFBFBD><EFBFBD>] _texImage2D <20>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
void RenderSystem::_texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) {
|
||||
assertOnRenderThread();
|
||||
glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
|
||||
}
|
||||
|
||||
void RenderSystem::texParameteri(GLenum target, GLenum pname, GLint param) { RENDER_SYSTEM_QUEUE_CALL(_texParameteri, target, pname, param); }
|
||||
void RenderSystem::_texParameteri(GLenum t, GLenum p, GLint v) { assertOnRenderThread(); glTexParameteri(t, p, v); }
|
||||
void RenderSystem::setTextureMinFilter(GLenum filter) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); }
|
||||
void RenderSystem::setTextureMagFilter(GLenum filter) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); }
|
||||
void RenderSystem::setTextureWrapS(GLenum wrap) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); }
|
||||
void RenderSystem::setTextureWrapT(GLenum wrap) { texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); }
|
||||
GLuint RenderSystem::createDefaultTexture() {
|
||||
assertOnRenderThread();
|
||||
GLuint textureId = genTextures();
|
||||
_bindTexture(textureId);
|
||||
unsigned char whitePixel[] = { 255, 255, 255, 255 };
|
||||
texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, whitePixel);
|
||||
_texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
_texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
_texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
_texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
_bindTexture(0);
|
||||
return textureId;
|
||||
}
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
void RenderSystem::enableVertexAttribArray(GLuint i) { RENDER_SYSTEM_QUEUE_CALL(_enableVertexAttribArray, i); }
|
||||
void RenderSystem::_enableVertexAttribArray(GLuint i) { assertOnRenderThread(); glEnableVertexAttribArray(i); }
|
||||
void RenderSystem::disableVertexAttribArray(GLuint i) { RENDER_SYSTEM_QUEUE_CALL(_disableVertexAttribArray, i); }
|
||||
void RenderSystem::_disableVertexAttribArray(GLuint i) { assertOnRenderThread(); glDisableVertexAttribArray(i); }
|
||||
void RenderSystem::vertexAttribPointer(GLuint i, GLint s, GLenum t, GLboolean n, GLsizei st, const void* p) { RENDER_SYSTEM_QUEUE_CALL(_vertexAttribPointer, i, s, t, n, st, p); }
|
||||
void RenderSystem::_vertexAttribPointer(GLuint i, GLint s, GLenum t, GLboolean n, GLsizei st, const void* p) { assertOnRenderThread(); glVertexAttribPointer(i, s, t, n, st, p); }
|
||||
|
||||
// ================== <20><><EFBFBD>߷<EFBFBD><DFB7><EFBFBD> ==================
|
||||
void RenderSystem::readPixels(int x, int y, int w, int h, GLenum f, GLenum t, void* p) { assertOnRenderThread(); glReadPixels(x, y, w, h, f, t, p); }
|
||||
|
||||
// [<5B><><EFBFBD><EFBFBD>] _readPixels <20>Ķ<EFBFBD><C4B6><EFBFBD>
|
||||
void RenderSystem::_readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels) {
|
||||
assertOnRenderThread();
|
||||
glReadPixels(x, y, width, height, format, type, pixels);
|
||||
}
|
||||
|
||||
bool RenderSystem::isExtensionSupported(const std::string& ext) {
|
||||
assertOnRenderThread();
|
||||
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
return strstr(extensions, ext.c_str()) != nullptr;
|
||||
}
|
||||
void RenderSystem::pixelStore(GLenum pname, GLint param) { RENDER_SYSTEM_QUEUE_CALL(_pixelStore, pname, param); }
|
||||
void RenderSystem::_pixelStore(GLenum p, GLint v) { assertOnRenderThread(); glPixelStorei(p, v); }
|
||||
std::string RenderSystem::getVendor() { assertOnRenderThread(); return (const char*)glGetString(GL_VENDOR); }
|
||||
std::string RenderSystem::getRenderer() { assertOnRenderThread(); return (const char*)glGetString(GL_RENDERER); }
|
||||
std::string RenderSystem::getOpenGLVersion() { assertOnRenderThread(); return (const char*)glGetString(GL_VERSION); }
|
||||
std::string RenderSystem::getGLSLVersion() { assertOnRenderThread(); return (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); }
|
||||
void RenderSystem::logDetailedGLInfo() {
|
||||
assertOnRenderThread();
|
||||
s_Logger->info("=== OpenGL System Information ===");
|
||||
s_Logger->info("Vendor: {}", getVendor());
|
||||
s_Logger->info("Renderer: {}", getRenderer());
|
||||
s_Logger->info("OpenGL Version: {}", getOpenGLVersion());
|
||||
s_Logger->info("GLSL Version: {}", getGLSLVersion());
|
||||
GLint val;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val);
|
||||
s_Logger->info("Max Texture Size: {}", val);
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &val);
|
||||
s_Logger->info("Max Vertex Attributes: {}", val);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &val);
|
||||
s_Logger->info("Max Texture Units: {}", val);
|
||||
}
|
||||
void RenderSystem::setupDefaultState() {
|
||||
beginInitialization();
|
||||
clearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
viewport(0, 0, s_ViewportWidth, s_ViewportHeight);
|
||||
enableBlend();
|
||||
defaultBlendFunc();
|
||||
disableDepthTest();
|
||||
finishInitialization();
|
||||
}
|
||||
void RenderSystem::checkGLError(const std::string& operation) { RENDER_SYSTEM_QUEUE_CALL(_checkGLError, operation); }
|
||||
void RenderSystem::_checkGLError(const std::string& op) {
|
||||
assertOnRenderThread();
|
||||
GLenum error;
|
||||
while ((error = glGetError()) != GL_NO_ERROR) {
|
||||
s_Logger->error("OpenGL error during [{}]: {} ({})", op, getGLErrorString(error), error);
|
||||
}
|
||||
}
|
||||
std::string RenderSystem::getGLErrorString(GLenum error) {
|
||||
switch (error) {
|
||||
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
|
||||
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
|
||||
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
|
||||
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
default: return "Unknown (" + std::to_string(error) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
// ================== <20><>ȡ״̬ ==================
|
||||
int RenderSystem::getViewportWidth() { return s_ViewportWidth; }
|
||||
int RenderSystem::getViewportHeight() { return s_ViewportHeight; }
|
||||
glm::vec4 RenderSystem::getClearColor() { return s_ClearColorValue; }
|
||||
int RenderSystem::getQueueSize() {
|
||||
std::lock_guard<std::mutex> lock(s_RenderQueueMutex);
|
||||
return s_RenderQueue.size();
|
||||
}
|
||||
276
Vivid2DRenderer/systems/RenderSystem.h
Normal file
276
Vivid2DRenderer/systems/RenderSystem.h
Normal file
@@ -0,0 +1,276 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
// <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD> spdlog::logger <20>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD><C4BC>а<EFBFBD><D0B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
namespace spdlog {
|
||||
class logger;
|
||||
}
|
||||
|
||||
class RenderSystem {
|
||||
public:
|
||||
RenderSystem() = delete;
|
||||
~RenderSystem() = delete;
|
||||
RenderSystem(const RenderSystem&) = delete;
|
||||
RenderSystem& operator=(const RenderSystem&) = delete;
|
||||
|
||||
|
||||
// ================== <20><>־ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD> ==================
|
||||
/**
|
||||
* @brief <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>־ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼʱ<CABC><CAB1><EFBFBD>á<EFBFBD>
|
||||
*/
|
||||
static void InitializeLogging();
|
||||
|
||||
/**
|
||||
* @brief <20>ر<EFBFBD><D8B1><EFBFBD>־ϵͳ<CFB5><CDB3>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ˢ<EFBFBD>¡<EFBFBD>
|
||||
*/
|
||||
static void ShutdownLogging();
|
||||
|
||||
// ================== <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>̹߳<DFB3><CCB9><EFBFBD> ==================
|
||||
static void initRenderThread();
|
||||
static void beginInitialization();
|
||||
static void finishInitialization();
|
||||
static bool isOnRenderThread();
|
||||
static bool isInInitPhase();
|
||||
static void assertOnRenderThread();
|
||||
static void assertOnRenderThreadOrInit();
|
||||
|
||||
// ================== <20><>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
static void recordRenderCall(std::function<void()>&& renderCall);
|
||||
static void replayQueue();
|
||||
|
||||
// ================== OpenGL ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ ==================
|
||||
static void enable(GLenum capability);
|
||||
static void disable(GLenum capability);
|
||||
static void pushState();
|
||||
static void popState();
|
||||
static int getStateStackSize();
|
||||
static void clearColor(float r, float g, float b, float a);
|
||||
static void clear(GLbitfield mask);
|
||||
static void viewport(int x, int y, int width, int height);
|
||||
|
||||
// ================== VAO / VBO / EBO <20><><EFBFBD><EFBFBD> ==================
|
||||
static GLuint GenVertexArrays();
|
||||
static void DeleteVertexArrays(GLuint vao);
|
||||
static void BindVertexArray(GLuint vao);
|
||||
static GLuint GenBuffers();
|
||||
static void DeleteBuffers(GLuint buffer);
|
||||
static void BindBuffer(GLenum target, GLuint buffer);
|
||||
static void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||
|
||||
// ================== Uniform <20><><EFBFBD><EFBFBD> ==================
|
||||
static void uniform1i(GLint location, int value);
|
||||
static void uniform1f(GLint location, float value);
|
||||
static void uniform2f(GLint location, float x, float y);
|
||||
static void uniform3f(GLint location, float x, float y, float z);
|
||||
static void uniform4f(GLint location, float x, float y, float z, float w);
|
||||
static void uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
static void uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
static void uniform2f(GLint location, const glm::vec2& vec);
|
||||
static void uniform3f(GLint location, const glm::vec3& vec);
|
||||
static void uniform4f(GLint location, const glm::vec4& vec);
|
||||
static void uniformMatrix3(GLint location, const glm::mat3& matrix, bool transpose = false);
|
||||
static void uniformMatrix4(GLint location, const glm::mat4& matrix, bool transpose = false);
|
||||
static GLint getUniformLocation(GLuint program, const std::string& name);
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
static void lineWidth(float width);
|
||||
static void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
||||
static void drawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD>ģʽ ==================
|
||||
static void enableBlend();
|
||||
static void disableBlend();
|
||||
static void blendFunc(GLenum sfactor, GLenum dfactor);
|
||||
static void defaultBlendFunc();
|
||||
|
||||
// ================== <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
static GLuint createProgram();
|
||||
static GLint getCurrentProgram();
|
||||
static void attachShader(GLuint program, GLuint shader);
|
||||
static void linkProgram(GLuint program);
|
||||
static GLint getProgrami(GLuint program, GLenum pname);
|
||||
static std::string getProgramInfoLog(GLuint program);
|
||||
static void detachShader(GLuint program, GLuint shader);
|
||||
static void deleteProgram(GLuint program);
|
||||
static GLuint linkProgram(GLuint vertexShader, GLuint fragmentShader);
|
||||
static GLuint linkProgram(GLuint vertexShader, GLuint geometryShader, GLuint fragmentShader);
|
||||
static void useProgram(GLuint program);
|
||||
|
||||
// ================== <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
static GLuint createShader(GLenum type);
|
||||
static void shaderSource(GLuint shader, const std::string& source);
|
||||
static void compileShader(GLuint shader);
|
||||
static GLint getShaderi(GLuint shader, GLenum pname);
|
||||
static std::string getShaderInfoLog(GLuint shader);
|
||||
static void deleteShader(GLuint shader);
|
||||
static GLuint compileShader(GLenum type, const std::string& source);
|
||||
|
||||
// ================== <20><><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD> ==================
|
||||
static void depthFunc(GLenum func);
|
||||
static void depthMask(bool flag);
|
||||
static void clearDepth(double depth);
|
||||
static void enableDepthTest();
|
||||
static void disableDepthTest();
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
static void bindTexture(GLuint texture);
|
||||
static void getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
|
||||
static void activeTexture(GLenum texture);
|
||||
static GLuint genTextures();
|
||||
static void deleteTextures(GLuint texture);
|
||||
static void texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
|
||||
static void texParameteri(GLenum target, GLenum pname, GLint param);
|
||||
static void setTextureMinFilter(GLenum filter);
|
||||
static void setTextureMagFilter(GLenum filter);
|
||||
static void setTextureWrapS(GLenum wrap);
|
||||
static void setTextureWrapT(GLenum wrap);
|
||||
static GLuint createDefaultTexture();
|
||||
|
||||
// ================== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ==================
|
||||
static void enableVertexAttribArray(GLuint index);
|
||||
static void disableVertexAttribArray(GLuint index);
|
||||
static void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
|
||||
|
||||
// ================== <20><><EFBFBD>߷<EFBFBD><DFB7><EFBFBD> ==================
|
||||
static void readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
|
||||
static bool isExtensionSupported(const std::string& extension);
|
||||
static void pixelStore(GLenum pname, GLint param);
|
||||
static std::string getVendor();
|
||||
static std::string getRenderer();
|
||||
static std::string getOpenGLVersion();
|
||||
static std::string getGLSLVersion();
|
||||
static void logDetailedGLInfo();
|
||||
static void setupDefaultState();
|
||||
static void checkGLError(const std::string& operation);
|
||||
|
||||
// ================== <20><>ȡ״̬ ==================
|
||||
static int getViewportWidth();
|
||||
static int getViewportHeight();
|
||||
static glm::vec4 getClearColor();
|
||||
static int getQueueSize();
|
||||
|
||||
private:
|
||||
struct RenderState;
|
||||
// ˽<>еġ<D0B5>ֱ<EFBFBD><D6B1>ִ<EFBFBD><D6B4>GL<47><4C><EFBFBD>õİ汾
|
||||
static void _enable(GLenum capability);
|
||||
static void _disable(GLenum capability);
|
||||
static void _pushState();
|
||||
static void _popState();
|
||||
static void _clearColor(float r, float g, float b, float a);
|
||||
static void _clear(GLbitfield mask);
|
||||
static void _viewport(int x, int y, int width, int height);
|
||||
static void _glDeleteVertexArrays(GLuint vao);
|
||||
static void _uniform1i(GLint location, int value);
|
||||
static void _uniform1f(GLint location, float value);
|
||||
static void _uniform2f(GLint location, float x, float y);
|
||||
static void _uniform3f(GLint location, float x, float y, float z);
|
||||
static void _uniform4f(GLint location, float x, float y, float z, float w);
|
||||
static void _uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
static void _uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
static void _lineWidth(float width);
|
||||
static void _drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
|
||||
static void _drawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
static void _glBindVertexArray(GLuint vao);
|
||||
static void _enableBlend();
|
||||
static void _disableBlend();
|
||||
static void _blendFunc(GLenum sfactor, GLenum dfactor);
|
||||
static void _attachShader(GLuint program, GLuint shader);
|
||||
static void _linkProgram(GLuint program);
|
||||
static void _detachShader(GLuint program, GLuint shader);
|
||||
static void _deleteProgram(GLuint program);
|
||||
static void _useProgram(GLuint program);
|
||||
static void _shaderSource(GLuint shader, const std::string& source);
|
||||
static void _compileShader(GLuint shader);
|
||||
static void _deleteShader(GLuint shader);
|
||||
static void _depthFunc(GLenum func);
|
||||
static void _depthMask(bool flag);
|
||||
static void _clearDepth(double depth);
|
||||
static void _enableDepthTest();
|
||||
static void _disableDepthTest();
|
||||
static void _bindTexture(GLuint texture);
|
||||
static void _getTexImage(GLenum target, GLint level, GLenum format, GLenum type, void* pixels);
|
||||
static void _activeTexture(GLenum texture);
|
||||
static void _deleteTextures(GLuint texture);
|
||||
static void _texImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
|
||||
static void _texParameteri(GLenum target, GLenum pname, GLint param);
|
||||
static void _glBindBuffer(GLenum target, GLuint buffer);
|
||||
static void _glBufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||
static void _glDeleteBuffers(GLuint buffer);
|
||||
static void _enableVertexAttribArray(GLuint index);
|
||||
static void _disableVertexAttribArray(GLuint index);
|
||||
static void _vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
|
||||
static void _readPixels(int x, int y, int width, int height, GLenum format, GLenum type, void* pixels);
|
||||
static void _pixelStore(GLenum pname, GLint param);
|
||||
static void _checkGLError(const std::string& operation);
|
||||
|
||||
|
||||
static std::string getGLErrorString(GLenum error);
|
||||
|
||||
// <20><>̬<EFBFBD><CCAC>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>
|
||||
static std::thread::id s_RenderThreadId;
|
||||
static std::atomic<bool> s_IsInInit;
|
||||
static std::queue<std::function<void()>> s_RenderQueue;
|
||||
static std::mutex s_RenderQueueMutex;
|
||||
static std::atomic<bool> s_IsReplayingQueue;
|
||||
|
||||
// ================== RenderState <20>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5> ==================
|
||||
struct RenderSystem::RenderState {
|
||||
GLint currentProgram = 0;
|
||||
GLboolean blendEnabled = GL_FALSE;
|
||||
GLboolean depthTestEnabled = GL_FALSE;
|
||||
GLint blendSrcFactor = GL_SRC_ALPHA;
|
||||
GLint blendDstFactor = GL_ONE_MINUS_SRC_ALPHA;
|
||||
GLint activeTexture = GL_TEXTURE0;
|
||||
GLint boundTexture = 0;
|
||||
glm::vec4 clearColor{ 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
glm::ivec4 viewport{ 0, 0, 800, 600 };
|
||||
|
||||
|
||||
RenderState() {
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
|
||||
blendEnabled = glIsEnabled(GL_BLEND);
|
||||
depthTestEnabled = glIsEnabled(GL_DEPTH_TEST);
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcFactor);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &blendDstFactor);
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, &clearColor[0]);
|
||||
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
|
||||
while (glGetError() != GL_NO_ERROR) {}
|
||||
}
|
||||
|
||||
void restore() {
|
||||
glViewport(viewport.x, viewport.y, viewport.z, viewport.w);
|
||||
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
|
||||
glUseProgram(currentProgram);
|
||||
glActiveTexture(activeTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, boundTexture);
|
||||
if (blendEnabled) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
||||
glBlendFunc(blendSrcFactor, blendDstFactor);
|
||||
if (depthTestEnabled) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||
while (glGetError() != GL_NO_ERROR) {}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static std::stack<RenderState> s_StateStack;
|
||||
|
||||
static int s_ViewportWidth;
|
||||
static int s_ViewportHeight;
|
||||
static glm::vec4 s_ClearColorValue;
|
||||
|
||||
static std::shared_ptr<spdlog::logger> s_Logger;
|
||||
|
||||
};
|
||||
182
Vivid2DRenderer/systems/buffer/BufferBuilder.cpp
Normal file
182
Vivid2DRenderer/systems/buffer/BufferBuilder.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BufferUploader.h"
|
||||
#include "BufferBuilder.h"
|
||||
#include <glad/glad.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
namespace Buffer {
|
||||
|
||||
// ==========================================================
|
||||
// RenderState ʵ<><CAB5>
|
||||
// ==========================================================
|
||||
|
||||
void RenderState::saveCurrentState() {
|
||||
GLint currentProgram = 0;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
|
||||
this->shaderProgram = static_cast<unsigned int>(currentProgram);
|
||||
|
||||
GLint boundTexture = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
|
||||
this->textureId = static_cast<unsigned int>(boundTexture);
|
||||
|
||||
GLint activeTextureUnit = 0;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTextureUnit);
|
||||
this->textureUnit = activeTextureUnit - GL_TEXTURE0;
|
||||
|
||||
this->depthTest = glIsEnabled(GL_DEPTH_TEST);
|
||||
this->blending = glIsEnabled(GL_BLEND);
|
||||
|
||||
while (glGetError() != GL_NO_ERROR) {}
|
||||
}
|
||||
|
||||
void RenderState::applyState() const {
|
||||
// <20>ָ<EFBFBD> Program
|
||||
if (shaderProgram != 0) {
|
||||
glUseProgram(shaderProgram);
|
||||
}
|
||||
|
||||
// <20>ָ<EFBFBD> Texture
|
||||
if (textureId != 0) {
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
}
|
||||
|
||||
// <20>ָ<EFBFBD> Blending/Depth
|
||||
if (this->blending) {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if (this->depthTest) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==========================================================
|
||||
// BufferBuilder ʵ<><CAB5>
|
||||
// ==========================================================
|
||||
|
||||
// Ĭ<>Ϲ<EFBFBD><CFB9>캯<EFBFBD><ECBAAF> (256 floats -> 64 <20><><EFBFBD><EFBFBD>)
|
||||
BufferBuilder::BufferBuilder() : BufferBuilder(256) {}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>캯<EFBFBD><ECBAAF>
|
||||
BufferBuilder::BufferBuilder(int initialFloatCapacity)
|
||||
: array(std::max(16, initialFloatCapacity)), size(0), vertexCount(0)
|
||||
{
|
||||
// Ĭ<>ϻ<EFBFBD><CFBB><EFBFBD>ģʽ
|
||||
this->mode = GL_TRIANGLES;
|
||||
// ȷ<><C8B7> array <20><>ʼ<EFBFBD>ǿյ<C7BF>
|
||||
this->array.clear();
|
||||
}
|
||||
|
||||
void BufferBuilder::begin(int glMode, int estimatedVertexCount) {
|
||||
this->mode = glMode;
|
||||
this->size = 0;
|
||||
this->vertexCount = 0;
|
||||
this->array.clear();
|
||||
|
||||
// <20><><EFBFBD>浱ǰ<E6B5B1><C7B0>Ⱦ״̬
|
||||
if (!stateSaved) {
|
||||
renderState.saveCurrentState();
|
||||
stateSaved = true;
|
||||
}
|
||||
|
||||
if (estimatedVertexCount > 0) {
|
||||
this->array.reserve(estimatedVertexCount * COMPONENTS_PER_VERTEX);
|
||||
}
|
||||
}
|
||||
|
||||
void BufferBuilder::setTexture(unsigned int textureId, int textureUnit) {
|
||||
this->renderState.textureId = textureId;
|
||||
this->renderState.textureUnit = textureUnit;
|
||||
}
|
||||
|
||||
void BufferBuilder::setShader(unsigned int programId) {
|
||||
this->renderState.shaderProgram = programId;
|
||||
}
|
||||
|
||||
void BufferBuilder::setColor(const glm::vec4& color) {
|
||||
this->renderState.color = color;
|
||||
}
|
||||
|
||||
void BufferBuilder::setOpacity(float opacity) {
|
||||
this->renderState.opacity = opacity;
|
||||
}
|
||||
|
||||
void BufferBuilder::vertex(float x, float y, float u, float v) {
|
||||
this->array.push_back(x);
|
||||
this->array.push_back(y);
|
||||
this->array.push_back(u);
|
||||
this->array.push_back(v);
|
||||
this->size = this->array.size();
|
||||
this->vertexCount++;
|
||||
}
|
||||
|
||||
std::unique_ptr<BuiltBuffer> BufferBuilder::end() {
|
||||
if (vertexCount == 0) return nullptr;
|
||||
|
||||
RenderSystem::assertOnRenderThread();
|
||||
|
||||
// 1. <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD><CDB0><EFBFBD> GPU <20><>Դ
|
||||
unsigned int vao = RenderSystem::GenVertexArrays();
|
||||
unsigned int vbo = RenderSystem::GenBuffers();
|
||||
|
||||
RenderSystem::BindVertexArray(vao);
|
||||
RenderSystem::BindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
|
||||
// 2. <20>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD> RenderSystem <20>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GL_ARRAY_BUFFER <20><> GL_DYNAMIC_DRAW
|
||||
RenderSystem::BufferData(GL_ARRAY_BUFFER, this->array.size() * sizeof(float),
|
||||
this->array.data(), GL_DYNAMIC_DRAW);
|
||||
|
||||
// 3. <20><><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Location 0: Position, Location 1: TexCoord)
|
||||
// Position (location 0): 2 floats, offset 0
|
||||
RenderSystem::enableVertexAttribArray(0);
|
||||
RenderSystem::vertexAttribPointer(0, 2, GL_FLOAT, false,
|
||||
COMPONENTS_PER_VERTEX * sizeof(float), 0);
|
||||
|
||||
// Texture Coords (location 1): 2 floats, offset 2 * sizeof(float)
|
||||
RenderSystem::enableVertexAttribArray(1);
|
||||
RenderSystem::vertexAttribPointer(1, 2, GL_FLOAT, false,
|
||||
COMPONENTS_PER_VERTEX * sizeof(float),
|
||||
reinterpret_cast<const void*>(2 * sizeof(float)));
|
||||
|
||||
// 4. <20><><EFBFBD><EFBFBD>
|
||||
RenderSystem::BindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
RenderSystem::BindVertexArray(0);
|
||||
|
||||
// 5. <20><><EFBFBD><EFBFBD> BuiltBuffer
|
||||
RenderState stateCopy = renderState.copy();
|
||||
stateSaved = false;
|
||||
|
||||
return std::make_unique<BuiltBuffer>(vao, vbo, vertexCount, mode, stateCopy);
|
||||
}
|
||||
|
||||
void BufferBuilder::endImmediate() {
|
||||
std::unique_ptr<BuiltBuffer> buffer = end();
|
||||
if (buffer != nullptr) {
|
||||
BufferUploader::drawWithShader(std::move(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
void BufferBuilder::dispose(const BuiltBuffer* buffer) {
|
||||
if (buffer != nullptr) {
|
||||
RenderSystem::DeleteVertexArrays(buffer->vao);
|
||||
RenderSystem::DeleteBuffers(buffer->vbo);
|
||||
}
|
||||
}
|
||||
|
||||
void BufferBuilder::clear() {
|
||||
this->array.clear();
|
||||
this->size = 0;
|
||||
this->vertexCount = 0;
|
||||
}
|
||||
} // namespace Buffer
|
||||
131
Vivid2DRenderer/systems/buffer/BufferBuilder.h
Normal file
131
Vivid2DRenderer/systems/buffer/BufferBuilder.h
Normal file
@@ -0,0 +1,131 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щͷ<D0A9>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>д<EFBFBD><D0B4><EFBFBD>
|
||||
#include "../../systems/RenderSystem.h"
|
||||
|
||||
namespace Buffer {
|
||||
|
||||
/**
|
||||
* @brief <20><>Ⱦ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><E1B9B9>
|
||||
*/
|
||||
struct RenderState {
|
||||
// <20><>Ⱦ״̬<D7B4><CCAC><EFBFBD><EFBFBD> (<28><>Ӧ Java <20>е<EFBFBD> RenderState)
|
||||
unsigned int textureId = 0;
|
||||
int textureUnit = 0;
|
||||
unsigned int shaderProgram = 0;
|
||||
glm::vec4 color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
float opacity = 1.0f;
|
||||
int blendMode = 0;
|
||||
bool depthTest = false;
|
||||
bool blending = true;
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD>浱ǰ OpenGL ״̬ (Program, Texture, Blending/Depth)
|
||||
*/
|
||||
void saveCurrentState();
|
||||
|
||||
/**
|
||||
* @brief Ӧ<>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD> OpenGL ״̬ (<28><><EFBFBD><EFBFBD> Program <20><> Texture<72><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GL ״̬)
|
||||
*/
|
||||
void applyState() const;
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>״̬
|
||||
*/
|
||||
RenderState copy() const {
|
||||
RenderState copy;
|
||||
copy.textureId = this->textureId;
|
||||
copy.textureUnit = this->textureUnit;
|
||||
copy.shaderProgram = this->shaderProgram;
|
||||
copy.color = this->color; // glm::vec4 Ĭ<><C4AC>֧<EFBFBD><D6A7>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
|
||||
copy.opacity = this->opacity;
|
||||
copy.blendMode = this->blendMode;
|
||||
copy.depthTest = this->depthTest;
|
||||
copy.blending = this->blending;
|
||||
return copy;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵĻ<C9B5><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ
|
||||
*/
|
||||
struct BuiltBuffer {
|
||||
unsigned int vao;
|
||||
unsigned int vbo;
|
||||
int vertexCount;
|
||||
int mode; // GL_TRIANGLES, GL_LINE_LOOP <20><>
|
||||
RenderState renderState;
|
||||
|
||||
BuiltBuffer(unsigned int vao, unsigned int vbo, int vertexCount, int mode, const RenderState& state)
|
||||
: vao(vao), vbo(vbo), vertexCount(vertexCount), mode(mode), renderState(state) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief <20><EFBFBD> BufferBuilder<65><72><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD><DAB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ի<EFBFBD><D4BB>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD>塣
|
||||
* ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD> float x, float y, float u, float v <20><><EFBFBD><EFBFBD>4<EFBFBD><34> float<61><74>
|
||||
*/
|
||||
class BufferBuilder {
|
||||
private:
|
||||
static constexpr int COMPONENTS_PER_VERTEX = 4; // x,y,u,v
|
||||
std::vector<float> array;
|
||||
int size; // ʵ<>ʴ洢<CAB4><E6B4A2> float <20><><EFBFBD><EFBFBD> (array.size())
|
||||
int vertexCount;
|
||||
int mode; // GL mode
|
||||
RenderState renderState;
|
||||
bool stateSaved = false;
|
||||
public:
|
||||
BufferBuilder();
|
||||
explicit BufferBuilder(int initialFloatCapacity);
|
||||
|
||||
/**
|
||||
* @brief <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ƶ<EFBFBD> GL ģʽ (<28><><EFBFBD><EFBFBD> GL_LINE_LOOP)
|
||||
*/
|
||||
void begin(int glMode, int estimatedVertexCount);
|
||||
|
||||
void setTexture(unsigned int textureId, int textureUnit);
|
||||
void setShader(unsigned int programId);
|
||||
void setColor(const glm::vec4& color);
|
||||
void setOpacity(float opacity);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD>Ӷ<EFBFBD><D3B6>㣺x,y,u,v
|
||||
*/
|
||||
void vertex(float x, float y, float u, float v);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BuiltBuffer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߸<EFBFBD><DFB8><EFBFBD> dispose<73><65>
|
||||
*/
|
||||
std::unique_ptr<BuiltBuffer> end();
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD>ͷ<EFBFBD> GPU <20><>Դ<EFBFBD><D4B4>
|
||||
*/
|
||||
void endImmediate();
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GPU <20><>Դ<EFBFBD><D4B4>
|
||||
*/
|
||||
static void dispose(const BuiltBuffer* buffer);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void clear();
|
||||
|
||||
int getVertexCount() const {
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
bool isEmpty() const {
|
||||
return vertexCount == 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Buffer
|
||||
107
Vivid2DRenderer/systems/buffer/BufferUploader.cpp
Normal file
107
Vivid2DRenderer/systems/buffer/BufferUploader.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "BufferUploader.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
namespace Buffer {
|
||||
|
||||
void BufferUploader::applyRenderState(const RenderState& state) {
|
||||
// 1. Ӧ<><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (state.textureId != 0) {
|
||||
RenderSystem::activeTexture(GL_TEXTURE0 + state.textureUnit);
|
||||
RenderSystem::bindTexture(state.textureId);
|
||||
}
|
||||
|
||||
// 2. Ӧ<><D3A6><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
|
||||
unsigned int currentProgram = 0;
|
||||
if (state.shaderProgram != 0) {
|
||||
currentProgram = state.shaderProgram;
|
||||
RenderSystem::useProgram(state.shaderProgram);
|
||||
}
|
||||
else {
|
||||
// <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC>û<EFBFBD><C3BB>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><EFBFBD><F3B6A8B5><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
GLint programId = 0;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &programId);
|
||||
currentProgram = static_cast<unsigned int>(programId);
|
||||
}
|
||||
|
||||
// 3. <20><><EFBFBD><EFBFBD> uColor Uniform (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Program ʱ<><CAB1><EFBFBD><EFBFBD>)
|
||||
if (currentProgram != 0) {
|
||||
GLint colorLoc = RenderSystem::getUniformLocation(currentProgram, "uColor");
|
||||
|
||||
if (colorLoc != -1) {
|
||||
// ʹ<><CAB9> RenderSystem::uniform4f <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||
RenderSystem::uniform4f(colorLoc,
|
||||
state.color.x, state.color.y, state.color.z, state.color.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
spdlog::debug("BufferUploader::applyRenderState: No shader program available for color setting.");
|
||||
}
|
||||
|
||||
// 4. Ӧ<>û<EFBFBD><C3BB><EFBFBD>ģʽ
|
||||
if (state.blending) {
|
||||
RenderSystem::enableBlend();
|
||||
// <20><><EFBFBD><EFBFBD> RenderSystem::defaultBlendFunc() <20><>װ<EFBFBD><D7B0> glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
RenderSystem::defaultBlendFunc();
|
||||
}
|
||||
else {
|
||||
RenderSystem::disableBlend();
|
||||
}
|
||||
|
||||
// 5. Ӧ<><D3A6><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD>
|
||||
if (state.depthTest) {
|
||||
RenderSystem::enableDepthTest();
|
||||
}
|
||||
else {
|
||||
RenderSystem::disableDepthTest();
|
||||
}
|
||||
}
|
||||
|
||||
void BufferUploader::restoreRenderState(const RenderState& previousState) {
|
||||
// <20>ָ<EFBFBD>֮ǰ<D6AE><C7B0>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RenderState::applyState() <20><>ʵ<EFBFBD>֡<EFBFBD>
|
||||
previousState.applyState();
|
||||
}
|
||||
|
||||
|
||||
// ==========================================================
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||
// ==========================================================
|
||||
|
||||
void BufferUploader::drawWithShader(std::unique_ptr<BuiltBuffer> buffer) {
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>
|
||||
if (!buffer) return;
|
||||
|
||||
RenderSystem::assertOnRenderThread();
|
||||
RenderState currentState;
|
||||
currentState.saveCurrentState();
|
||||
|
||||
try {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> -> <20><><EFBFBD><EFBFBD> unique_ptr ָ<><D6B8><EFBFBD><EFBFBD> BuiltBuffer <20><>Ա
|
||||
const RenderState& bufferState = buffer->renderState;
|
||||
applyRenderState(bufferState);
|
||||
|
||||
if (buffer->vao != 0) {
|
||||
RenderSystem::BindVertexArray(buffer->vao);
|
||||
}
|
||||
if (buffer->vertexCount > 0) {
|
||||
RenderSystem::drawArrays(buffer->mode, 0, buffer->vertexCount);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAO
|
||||
if (buffer->vao != 0) {
|
||||
RenderSystem::BindVertexArray(0);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
spdlog::error("BufferUploader drawing failed: {}", e.what());
|
||||
}
|
||||
restoreRenderState(currentState);
|
||||
BufferBuilder::dispose(buffer.get());
|
||||
}
|
||||
|
||||
} // namespace Buffer
|
||||
38
Vivid2DRenderer/systems/buffer/BufferUploader.h
Normal file
38
Vivid2DRenderer/systems/buffer/BufferUploader.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "BufferBuilder.h"
|
||||
#include "../../systems/RenderSystem.h"
|
||||
|
||||
namespace Buffer {
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>Ⱦ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAO <20><>ִ<EFBFBD>л<EFBFBD><D0BB>ơ<EFBFBD>
|
||||
*/
|
||||
class BufferUploader {
|
||||
public:
|
||||
/**
|
||||
* @brief ʹ<><CAB9><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8>
|
||||
* @param buffer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BuiltBuffer <20><> unique_ptr<74><72>
|
||||
*/
|
||||
static void drawWithShader(std::unique_ptr<BuiltBuffer> buffer);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> drawWithShader <20><>ͬ<EFBFBD><CDAC>
|
||||
*/
|
||||
static void draw(std::unique_ptr<BuiltBuffer> buffer) {
|
||||
drawWithShader(std::move(buffer));
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Ӧ<><D3A6>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ״̬<D7B4><CCAC>
|
||||
*/
|
||||
static void applyRenderState(const RenderState& state);
|
||||
|
||||
/**
|
||||
* @brief <20>ָ<EFBFBD><D6B8><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD>Ⱦ״̬<D7B4><CCAC>
|
||||
*/
|
||||
static void restoreRenderState(const RenderState& previousState);
|
||||
};
|
||||
|
||||
} // namespace Buffer
|
||||
33
Vivid2DRenderer/systems/buffer/Tesselator.cpp
Normal file
33
Vivid2DRenderer/systems/buffer/Tesselator.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "pch.h"
|
||||
#include "Tesselator.h"
|
||||
|
||||
#include "BufferBuilder.h"
|
||||
#include "BufferUploader.h"
|
||||
|
||||
namespace Buffer {
|
||||
Tesselator::Tesselator(int bufferSize) {
|
||||
// <20><>ʼ<EFBFBD><CABC> BufferBuilder<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><D7B2><EFBFBD><EFBFBD><EFBFBD>
|
||||
this->builder = std::make_unique<BufferBuilder>(bufferSize);
|
||||
}
|
||||
|
||||
Tesselator::Tesselator() : Tesselator(DEFAULT_BUFFER_SIZE) {}
|
||||
|
||||
Tesselator& Tesselator::getInstance() {
|
||||
RenderSystem::assertOnRenderThreadOrInit();
|
||||
static Tesselator INSTANCE;
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
void Tesselator::end() {
|
||||
RenderSystem::assertOnRenderThread();
|
||||
std::unique_ptr<BuiltBuffer> builtBuffer = this->builder->end();
|
||||
if (builtBuffer) {
|
||||
BufferUploader::drawWithShader(std::move(builtBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
BufferBuilder& Tesselator::getBuilder() {
|
||||
return *this->builder;
|
||||
}
|
||||
|
||||
} // namespace Buffer
|
||||
119
Vivid2DRenderer/systems/buffer/Tesselator.h
Normal file
119
Vivid2DRenderer/systems/buffer/Tesselator.h
Normal file
@@ -0,0 +1,119 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BufferBuilder.h"
|
||||
#include "../../systems/RenderSystem.h"
|
||||
|
||||
/**
|
||||
* @file BufferSystem.h
|
||||
* @brief Vivid2D <20><>Ⱦϵͳ<CFB5>ļ<EFBFBD>ʱģʽ<C4A3><CABD>Immediate Mode<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3>
|
||||
*
|
||||
* <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD>꣺<EFBFBD>ṩһ<E1B9A9><D2BB><EFBFBD><EFBFBD><F2B5A5A1><EFBFBD>Ч<EFBFBD>Ľӿڣ<D3BF><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* <20><>ʹ<EFBFBD><CAB9>һ<EFBFBD><D2BB> Draw Call <20>ύ<EFBFBD><E1BDBB> GPU <20><>Ⱦ<EFBFBD><C8BE>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD> GPU <20><>Դ<EFBFBD><D4B4>
|
||||
*
|
||||
* ==========================================================
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* ==========================================================
|
||||
*
|
||||
* 1. Tesselator (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
* ----------------------------
|
||||
* - <20><><EFBFBD>ã<EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD>ڵ㣬<DAB5><E3A3AC><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> BufferBuilder <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>
|
||||
* - <20>ӿڣ<D3BF>Tesselator::getInstance() <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Tesselator::getBuilder() <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* - <20><><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD>Tesselator::end()<29><><EFBFBD><EFBFBD><EFBFBD>ô˷<C3B4><CBB7><EFBFBD><EFBFBD>ᴥ<EFBFBD><E1B4A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (Builder -> Uploader)<29><>
|
||||
*
|
||||
* 2. BufferBuilder (<28><><EFBFBD>ݹ<EFBFBD><DDB9><EFBFBD><EFBFBD><EFBFBD>)
|
||||
* ----------------------------
|
||||
* - <20><><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CPU <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>x, y, u, v<><76><EFBFBD>͵<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>Ⱦ״̬ (RenderState)<29><>
|
||||
* - <20>ӿڣ<D3BF>begin() <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vertex() <20><><EFBFBD>Ӷ<EFBFBD><D3B6>㣻setTexture/setColor <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC>
|
||||
* - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>end() <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> BuiltBuffer ʵ<><CAB5><EFBFBD><EFBFBD>
|
||||
*
|
||||
* 3. BuiltBuffer (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
* --------------------------
|
||||
* - <20><><EFBFBD>ã<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݽṹ<DDBD><E1B9B9><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>Ҫ<EFBFBD><D2AA> GPU <20><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD> (VAO/VBO)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GL ģʽ<C4A3><CABD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> RenderState <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* - <20>ص㣺<D8B5><E3A3BA><EFBFBD><EFBFBD>Ȩͨ<C8A8><CDA8> std::unique_ptr ת<>ƣ<EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>Դֻ<D4B4><D6BB> Uploader <20><><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>Ρ<EFBFBD>
|
||||
*
|
||||
* 4. BufferUploader (<28><><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
* --------------------------------
|
||||
* - <20><><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD> BuiltBuffer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD>¼<EFBFBD><C2BC> RenderState Ӧ<>õ<EFBFBD> GL <20><><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD> VAO<41><4F>ִ<EFBFBD><D6B4> glDrawArrays <20><><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GPU <20><>Դ<EFBFBD><D4B4>
|
||||
* - <20><><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD>BufferUploader::drawWithShader(std::unique_ptr<BuiltBuffer> buffer)<29><>
|
||||
*
|
||||
* ==========================================================
|
||||
* <20><><EFBFBD><EFBFBD><CDB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>)
|
||||
* ==========================================================
|
||||
*
|
||||
* 1. <20><>ʼ<EFBFBD><CABC><EFBFBD>ͻ<EFBFBD>ȡ<EFBFBD><C8A1>
|
||||
* Tesselator& t = Tesselator::getInstance();
|
||||
* BufferBuilder& builder = t.getBuilder();
|
||||
*
|
||||
* 2. <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* builder.begin(GL_QUADS, 4); // Ԥ<>ƻ<EFBFBD><C6BB><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
|
||||
*
|
||||
* 3. <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC>
|
||||
* builder.setShader(myProgramId);
|
||||
* builder.setTexture(myTextureId, 0);
|
||||
* builder.setColor(glm::vec4(1.0f, 1.0f, 1.0f, 0.5f)); // <20><><EFBFBD><CDB8><EFBFBD><EFBFBD>ɫ
|
||||
*
|
||||
* 4. <20><><EFBFBD>Ӷ<EFBFBD><D3B6>㣨x, y, u, v<><76><EFBFBD><EFBFBD>
|
||||
* builder.vertex(10.0f, 10.0f, 0.0f, 0.0f);
|
||||
* builder.vertex(110.0f, 10.0f, 1.0f, 0.0f);
|
||||
* builder.vertex(110.0f, 110.0f, 1.0f, 1.0f);
|
||||
* builder.vertex(10.0f, 110.0f, 0.0f, 1.0f);
|
||||
*
|
||||
* 5. <20>ύ<EFBFBD><E1BDBB><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* t.end();
|
||||
* // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>GPU <20>ϵ<EFBFBD> VAO/VBO <20><>Դ<EFBFBD>ѱ<EFBFBD><D1B1>ͷš<CDB7>
|
||||
*
|
||||
*/
|
||||
namespace Buffer {
|
||||
|
||||
class BufferBuilder;
|
||||
|
||||
/**
|
||||
* @brief Tesselator <20>ࣺ<EFBFBD><E0A3BA>Ϊ BufferBuilder <20>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* * ְ<><D6B0><EFBFBD><EFBFBD>
|
||||
* 1. <20>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʡ<EFBFBD>
|
||||
* 2. <20><>װ BufferBuilder<65><72><EFBFBD>ṩһ<E1B9A9>µļ<C2B5><C4BC><EFBFBD><EFBFBD>幹<EFBFBD><E5B9B9><EFBFBD>ӿڡ<D3BF>
|
||||
* 3. <20><> end() <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BufferUploader <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
*/
|
||||
class Tesselator {
|
||||
private:
|
||||
static constexpr int DEFAULT_BUFFER_SIZE = 2097152; // 2MB floats
|
||||
|
||||
std::unique_ptr<BufferBuilder> builder; // BufferBuilder ʵ<><CAB5>
|
||||
|
||||
/**
|
||||
* @brief ˽<>й<EFBFBD><D0B9>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
explicit Tesselator(int bufferSize);
|
||||
|
||||
/**
|
||||
* @brief ˽<><CBBD>Ĭ<EFBFBD>Ϲ<EFBFBD><CFB9>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD>
|
||||
*/
|
||||
Tesselator();
|
||||
|
||||
public:
|
||||
Tesselator(const Tesselator&) = delete;
|
||||
Tesselator& operator=(const Tesselator&) = delete;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ Tesselator <20>ĵ<EFBFBD><C4B5><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD>̰߳<DFB3>ȫ<EFBFBD>ӳٳ<D3B3>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* * <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>߳<EFBFBD><DFB3>ϵ<EFBFBD><CFB5>û<EFBFBD><C3BB>ڳ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ε<D7B6><CEB5>á<EFBFBD>
|
||||
* @return Tesselator& <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
|
||||
*/
|
||||
static Tesselator& getInstance();
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> GPU<50><55><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
* * <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>߳<EFBFBD><DFB3>ϵ<EFBFBD><CFB5>á<EFBFBD>
|
||||
*/
|
||||
void end();
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD>ײ<EFBFBD><D7B2><EFBFBD> BufferBuilder <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC>
|
||||
* @return BufferBuilder&
|
||||
*/
|
||||
BufferBuilder& getBuilder();
|
||||
};
|
||||
|
||||
} // namespace Buffer
|
||||
48
Vivid2DRenderer/systems/sources/CompleteShader.h
Normal file
48
Vivid2DRenderer/systems/sources/CompleteShader.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
class ShaderProgram;
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><>Ӧ Java CompleteShader <20>ӿ<EFBFBD>)
|
||||
* <20><>װһ<D7B0><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>壬<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD>ݺͳ<DDBA>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><DFBC><EFBFBD>
|
||||
*/
|
||||
class CompleteShader {
|
||||
public:
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||
virtual ~CompleteShader() = default;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>塣
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
virtual const Shader& getVertexShader() const = 0;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡƬ<C8A1><C6AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>塣
|
||||
* @return Ƭ<><C6AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
virtual const Shader& getFragmentShader() const = 0;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
virtual std::string getShaderName() const = 0;
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true<75><65>
|
||||
*/
|
||||
virtual bool isDefaultShader() const = 0;
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* <20><>Ӧ Java <20>ӿ<EFBFBD><D3BF>е<EFBFBD> default <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param program <20><><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD> ShaderProgram <20><><EFBFBD><EFBFBD>ָ<EFBFBD>롣
|
||||
*/
|
||||
virtual void setDefaultUniforms(ShaderProgram* program) const {}
|
||||
};
|
||||
25
Vivid2DRenderer/systems/sources/Shader.h
Normal file
25
Vivid2DRenderer/systems/sources/Shader.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><>Ӧ Java Shader <20>ӿ<EFBFBD>)
|
||||
* <20><>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>綥<EFBFBD><E7B6A5><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
*/
|
||||
class Shader {
|
||||
public:
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||
virtual ~Shader() = default;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD> GLSL <20><><EFBFBD>롣
|
||||
* @return <20><><EFBFBD><EFBFBD> GLSL <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
virtual std::string getShaderCode() const = 0;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>͵<EFBFBD><CDB5>ԣ<EFBFBD><D4A3><EFBFBD>
|
||||
* @return <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
virtual std::string getShaderName() const = 0;
|
||||
};
|
||||
251
Vivid2DRenderer/systems/sources/ShaderManagement.cpp
Normal file
251
Vivid2DRenderer/systems/sources/ShaderManagement.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "ShaderManagement.h"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "../../systems/RenderSystem.h"
|
||||
#include "../../systems/sources/ShaderProgram.h"
|
||||
#include "../../systems/sources/Shader.h"
|
||||
#include "../../systems/sources/CompleteShader.h"
|
||||
#include "def/TextShader.h"
|
||||
#include "def/SolidColorShader.h"
|
||||
#include "def/Shader2D.h"
|
||||
|
||||
std::map<std::string, std::unique_ptr<ShaderProgram>> ShaderManagement::s_shaderMap;
|
||||
ShaderProgram* ShaderManagement::s_defaultProgram = nullptr;
|
||||
|
||||
/**
|
||||
* @brief ʹ<><CAB9> helper <20><><EFBFBD><EFBFBD><EFBFBD>ƹ<EFBFBD> std::initializer_list <20>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
* * * @return std::vector<std::unique_ptr<CompleteShader>>
|
||||
*/
|
||||
static std::vector<std::unique_ptr<CompleteShader>> create_shader_list()
|
||||
{
|
||||
std::vector<std::unique_ptr<CompleteShader>> list;
|
||||
list.push_back(std::make_unique<Shader2D>());
|
||||
list.push_back(std::make_unique<SolidColorShader>());
|
||||
list.push_back(std::make_unique<TextShader>());
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<CompleteShader>> ShaderManagement::s_shaderList = create_shader_list();
|
||||
|
||||
void ShaderManagement::compileAllShaders()
|
||||
{
|
||||
RenderSystem::assertOnRenderThread();
|
||||
|
||||
for (const auto& completeShader : s_shaderList) {
|
||||
compileShaderProgram(completeShader.get());
|
||||
}
|
||||
|
||||
if (s_defaultProgram == nullptr && !s_shaderMap.empty()) {
|
||||
s_defaultProgram = s_shaderMap.begin()->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::compileShaderProgram(const CompleteShader* completeShader)
|
||||
{
|
||||
const std::string& shaderName = completeShader->getShaderName();
|
||||
|
||||
try {
|
||||
const Shader& vertexShaderRef = completeShader->getVertexShader();
|
||||
GLuint vsId = compileShader(GL_VERTEX_SHADER, vertexShaderRef.getShaderCode(),
|
||||
vertexShaderRef.getShaderName());
|
||||
|
||||
const Shader& fragmentShaderRef = completeShader->getFragmentShader();
|
||||
GLuint fsId = compileShader(GL_FRAGMENT_SHADER, fragmentShaderRef.getShaderCode(),
|
||||
fragmentShaderRef.getShaderName());
|
||||
|
||||
GLuint programId = linkProgram(vsId, fsId, shaderName);
|
||||
std::unique_ptr<ShaderProgram> shaderProgram = std::make_unique<ShaderProgram>(programId);
|
||||
|
||||
if (completeShader->isDefaultShader()) {
|
||||
s_defaultProgram = shaderProgram.get();
|
||||
setupDefaultUniforms(s_defaultProgram);
|
||||
}
|
||||
else {
|
||||
completeShader->setDefaultUniforms(shaderProgram.get());
|
||||
}
|
||||
|
||||
s_shaderMap[shaderName] = std::move(shaderProgram);
|
||||
RenderSystem::deleteShader(vsId);
|
||||
RenderSystem::deleteShader(fsId);
|
||||
|
||||
spdlog::info("<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>: {}", shaderName);
|
||||
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
spdlog::error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>: {}", shaderName);
|
||||
std::cerr << "Shader compilation failed: " << shaderName << "\nError: " << e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setupDefaultUniforms(ShaderProgram* program)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
setUniformInt(program, "uTexture", 0);
|
||||
setUniformFloat(program, "uOpacity", 1.0f);
|
||||
setUniformVec4(program, "uColor", glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
setUniformInt(program, "uBlendMode", 0);
|
||||
setUniformInt(program, "uDebugMode", 0);
|
||||
setUniformInt(program, "uLightCount", 0);
|
||||
program->stop();
|
||||
RenderSystem::checkGLError("setupDefaultUniforms");
|
||||
}
|
||||
|
||||
GLuint ShaderManagement::compileShader(GLenum type, const std::string& source, const std::string& shaderName)
|
||||
{
|
||||
GLuint shaderId = RenderSystem::createShader(type);
|
||||
RenderSystem::shaderSource(shaderId, source);
|
||||
RenderSystem::compileShader(shaderId);
|
||||
if (RenderSystem::getShaderi(shaderId, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||
std::string log = RenderSystem::getShaderInfoLog(shaderId);
|
||||
RenderSystem::deleteShader(shaderId);
|
||||
throw std::runtime_error("<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD> [" + shaderName + "]:\n" + log);
|
||||
}
|
||||
return shaderId;
|
||||
}
|
||||
|
||||
GLuint ShaderManagement::linkProgram(GLuint vertexShaderId, GLuint fragmentShaderId, const std::string& programName)
|
||||
{
|
||||
GLuint programId = RenderSystem::createProgram();
|
||||
RenderSystem::attachShader(programId, vertexShaderId);
|
||||
RenderSystem::attachShader(programId, fragmentShaderId);
|
||||
RenderSystem::linkProgram(programId);
|
||||
if (RenderSystem::getProgrami(programId, GL_LINK_STATUS) != GL_TRUE) {
|
||||
std::string log = RenderSystem::getProgramInfoLog(programId);
|
||||
RenderSystem::deleteProgram(programId);
|
||||
throw std::runtime_error("<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD> [" + programName + "]:\n" + log);
|
||||
}
|
||||
validateProgram(programId, programName);
|
||||
return programId;
|
||||
}
|
||||
|
||||
void ShaderManagement::validateProgram(GLuint programId, const std::string& programName)
|
||||
{
|
||||
GLint validateStatus = RenderSystem::getProgrami(programId, GL_VALIDATE_STATUS);
|
||||
|
||||
if (validateStatus != GL_TRUE) {
|
||||
std::string log = RenderSystem::getProgramInfoLog(programId);
|
||||
spdlog::warn("<EFBFBD><EFBFBD>ɫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD> [{}]: {}", programName, log);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderProgram* ShaderManagement::getDefaultProgram()
|
||||
{
|
||||
return s_defaultProgram;
|
||||
}
|
||||
|
||||
ShaderProgram* ShaderManagement::getShaderProgram(const std::string& name)
|
||||
{
|
||||
auto it = s_shaderMap.find(name);
|
||||
if (it != s_shaderMap.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void ShaderManagement::cleanup()
|
||||
{
|
||||
RenderSystem::assertOnRenderThread();
|
||||
s_shaderMap.clear();
|
||||
s_shaderList.clear();
|
||||
s_defaultProgram = nullptr;
|
||||
spdlog::info("ShaderManagement cleanup completed.");
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformInt(ShaderProgram* program, const std::string& name, GLint value)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform1i(location, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformFloat(ShaderProgram* program, const std::string& name, GLfloat value)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform1f(location, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformVec2(ShaderProgram* program, const std::string& name, GLfloat x, GLfloat y)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform2f(location, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformVec2(ShaderProgram* program, const std::string& name, const glm::vec2& vec)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform2f(location, vec);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformVec3(ShaderProgram* program, const std::string& name, GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform3f(location, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformVec3(ShaderProgram* program, const std::string& name, const glm::vec3& vec)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform3f(location, vec);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformVec4(ShaderProgram* program, const std::string& name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform4f(location, x, y, z, w);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformVec4(ShaderProgram* program, const std::string& name, const glm::vec4& vec)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniform4f(location, vec);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagement::setUniformMat3(ShaderProgram* program, const std::string& name, const glm::mat3& matrix)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
GLint location = program->getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
RenderSystem::uniformMatrix3(location, matrix, false);
|
||||
}
|
||||
}
|
||||
112
Vivid2DRenderer/systems/sources/ShaderManagement.h
Normal file
112
Vivid2DRenderer/systems/sources/ShaderManagement.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
class ShaderProgram;
|
||||
class CompleteShader;
|
||||
class RenderSystem;
|
||||
|
||||
class Shader2D;
|
||||
class SolidColorShader;
|
||||
class TextShader;
|
||||
|
||||
/**
|
||||
* @brief <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ı<EFBFBD><C4B1>롢<EFBFBD><EBA1A2><EFBFBD>Ӻ<D3BA><CDB9><EFBFBD> (C++ <20><>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>)
|
||||
*/
|
||||
class ShaderManagement
|
||||
{
|
||||
private:
|
||||
// <20><>ֹʵ<D6B9><CAB5><EFBFBD><EFBFBD>
|
||||
ShaderManagement() = delete;
|
||||
ShaderManagement(const ShaderManagement&) = delete;
|
||||
ShaderManagement& operator=(const ShaderManagement&) = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD>ƴ洢<C6B4>ѱ<EFBFBD><D1B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* ʹ<><CAB9> std::unique_ptr <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ShaderProgram <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static std::map<std::string, std::unique_ptr<ShaderProgram>> s_shaderMap;
|
||||
|
||||
/**
|
||||
* @brief <20><>ɫ<EFBFBD><C9AB><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>Դ<EFBFBD><D4B4><EFBFBD>붨<EFBFBD><EBB6A8>
|
||||
* ע<>⣺<EFBFBD><E2A3BA> C++ <20>У<EFBFBD><D0A3><EFBFBD>̬<EFBFBD><CCAC>ʼ<EFBFBD><CABC><EFBFBD>б<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> .cpp <20>ļ<EFBFBD><C4BC>С<EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> std::vector<std::unique_ptr<CompleteShader>> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static std::vector<std::unique_ptr<CompleteShader>> s_shaderList;
|
||||
|
||||
/**
|
||||
* @brief Ĭ<><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static ShaderProgram* s_defaultProgram;
|
||||
|
||||
// --- <20><><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
|
||||
*/
|
||||
static void compileAllShaders();
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>Դ
|
||||
*/
|
||||
static void cleanup();
|
||||
|
||||
// --- Getter <20><><EFBFBD><EFBFBD> ---
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡĬ<C8A1><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static ShaderProgram* getDefaultProgram();
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD>ȡ<EFBFBD><C8A1>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static ShaderProgram* getShaderProgram(const std::string& name);
|
||||
|
||||
static void setUniformInt(ShaderProgram* program, const std::string& name, GLint value);
|
||||
static void setUniformFloat(ShaderProgram* program, const std::string& name, GLfloat value);
|
||||
|
||||
// Vec2/Vec3/Vec4 (ʹ<><CAB9> GLM)
|
||||
static void setUniformVec2(ShaderProgram* program, const std::string& name, GLfloat x, GLfloat y);
|
||||
static void setUniformVec2(ShaderProgram* program, const std::string& name, const glm::vec2& vec);
|
||||
static void setUniformVec3(ShaderProgram* program, const std::string& name, GLfloat x, GLfloat y, GLfloat z);
|
||||
static void setUniformVec3(ShaderProgram* program, const std::string& name, const glm::vec3& vec);
|
||||
static void setUniformVec4(ShaderProgram* program, const std::string& name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
static void setUniformVec4(ShaderProgram* program, const std::string& name, const glm::vec4& vec);
|
||||
|
||||
// Mat3 (ʹ<><CAB9> GLM)
|
||||
static void setUniformMat3(ShaderProgram* program, const std::string& name, const glm::mat3& matrix);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief <20><><EFBFBD>뵥<EFBFBD><EBB5A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static void compileShaderProgram(const CompleteShader* completeShader);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>uniformֵ
|
||||
*/
|
||||
static void setupDefaultUniforms(ShaderProgram* program);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>
|
||||
*/
|
||||
static GLuint compileShader(GLenum type, const std::string& source, const std::string& shaderName);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static GLuint linkProgram(GLuint vertexShaderId, GLuint fragmentShaderId, const std::string& programName);
|
||||
|
||||
/**
|
||||
* @brief <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><D6A4><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static void validateProgram(GLuint programId, const std::string& programName);
|
||||
};
|
||||
120
Vivid2DRenderer/systems/sources/ShaderProgram.cpp
Normal file
120
Vivid2DRenderer/systems/sources/ShaderProgram.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
ShaderProgram::ShaderProgram(GLuint programId)
|
||||
: m_programId(programId)
|
||||
{
|
||||
spdlog::info("ShaderProgram created with ID: {}", programId);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ShaderProgram::~ShaderProgram()
|
||||
{
|
||||
deleteProgram();
|
||||
spdlog::info("ShaderProgram {} destroyed.", m_programId);
|
||||
}
|
||||
|
||||
void ShaderProgram::use() const
|
||||
{
|
||||
glUseProgram(m_programId);
|
||||
}
|
||||
|
||||
void ShaderProgram::stop() const
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
GLint ShaderProgram::getUniformLocation(const std::string& name)
|
||||
{
|
||||
if (auto it = m_uniformCache.find(name); it != m_uniformCache.end()) {
|
||||
return it->second;
|
||||
}
|
||||
GLint location = glGetUniformLocation(m_programId, name.c_str());
|
||||
m_uniformCache[name] = location;
|
||||
if (location == -1) {
|
||||
spdlog::warn("Uniform '{}' not found in program ID: {}", name, m_programId);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
// --- uniform <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> (ʹ<><CAB9> name) ---
|
||||
|
||||
void ShaderProgram::setUniform1i(const std::string& name, GLint value)
|
||||
{
|
||||
GLint location = getUniformLocation(name);
|
||||
setUniform1i(location, value);
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniform1f(const std::string& name, GLfloat value)
|
||||
{
|
||||
GLint location = getUniformLocation(name);
|
||||
setUniform1f(location, value);
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniform2f(const std::string& name, GLfloat x, GLfloat y)
|
||||
{
|
||||
GLint location = getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
glUniform2f(location, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniform3f(const std::string& name, GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
GLint location = getUniformLocation(name);
|
||||
if (location != -1) {
|
||||
glUniform3f(location, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniform4f(const std::string& name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
GLint location = getUniformLocation(name);
|
||||
setUniform4f(location, x, y, z, w);
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniformMatrix3(const std::string& name, const glm::mat3& matrix)
|
||||
{
|
||||
GLint location = getUniformLocation(name);
|
||||
setUniformMatrix3(location, matrix);
|
||||
}
|
||||
|
||||
// --- uniform <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> (ʹ<><CAB9> location) ---
|
||||
|
||||
void ShaderProgram::setUniform1i(GLint location, GLint value)
|
||||
{
|
||||
if (location != -1) {
|
||||
glUniform1i(location, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniform1f(GLint location, GLfloat value)
|
||||
{
|
||||
if (location != -1) {
|
||||
glUniform1f(location, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
||||
{
|
||||
if (location != -1) {
|
||||
glUniform4f(location, x, y, z, w);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::setUniformMatrix3(GLint location, const glm::mat3& matrix)
|
||||
{
|
||||
if (location != -1) {
|
||||
glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::deleteProgram()
|
||||
{
|
||||
if (glIsProgram(m_programId)) {
|
||||
glDeleteProgram(m_programId);
|
||||
m_uniformCache.clear();
|
||||
}
|
||||
}
|
||||
57
Vivid2DRenderer/systems/sources/ShaderProgram.h
Normal file
57
Vivid2DRenderer/systems/sources/ShaderProgram.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
/**
|
||||
* @brief OpenGL<47><4C>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD>ࡣ
|
||||
* * <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD>OpenGL<47><4C>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2A3ACB0><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD>(uniform)<29><><EFBFBD><EFBFBD><EFBFBD>úͻ<C3BA><CDBB>档
|
||||
* <20><><EFBFBD>ǵ<EFBFBD><C7B5>̳<EFBFBD><CCB3>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>麯<EFBFBD><E9BAAF><EFBFBD><EFBFBD>
|
||||
*/
|
||||
class ShaderProgram
|
||||
{
|
||||
public:
|
||||
// <20><><EFBFBD>캯<EFBFBD><ECBAAF>
|
||||
explicit ShaderProgram(GLuint programId);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
|
||||
virtual ~ShaderProgram();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void use() const;
|
||||
|
||||
// ֹͣʹ<D6B9><CAB9><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void stop() const;
|
||||
|
||||
// <20><>ȡͳһ<CDB3><D2BB><EFBFBD><EFBFBD>(uniform)λ<>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
GLint getUniformLocation(const std::string& name);
|
||||
|
||||
// --- uniform <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> (ʹ<><CAB9> name) ---
|
||||
void setUniform1i(const std::string& name, GLint value);
|
||||
void setUniform1f(const std::string& name, GLfloat value);
|
||||
void setUniform2f(const std::string& name, GLfloat x, GLfloat y);
|
||||
void setUniform3f(const std::string& name, GLfloat x, GLfloat y, GLfloat z);
|
||||
void setUniform4f(const std::string& name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
|
||||
// ʹ<><CAB9> glm::mat3
|
||||
void setUniformMatrix3(const std::string& name, const glm::mat3& matrix);
|
||||
|
||||
// --- uniform <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> (ʹ<><CAB9> location) ---
|
||||
void setUniform1i(GLint location, GLint value);
|
||||
void setUniform1f(GLint location, GLfloat value);
|
||||
void setUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void setUniformMatrix3(GLint location, const glm::mat3& matrix);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>OpenGL<47><4C>Դ
|
||||
void deleteProgram();
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ID
|
||||
GLuint getProgramId() const { return m_programId; }
|
||||
|
||||
protected:
|
||||
const GLuint m_programId;
|
||||
std::map<std::string, GLint> m_uniformCache;
|
||||
};
|
||||
163
Vivid2DRenderer/systems/sources/def/Shader2D.cpp
Normal file
163
Vivid2DRenderer/systems/sources/def/Shader2D.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "Shader2D.h"
|
||||
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB> GLSL <20><><EFBFBD><EFBFBD> (<28><>Ӧ VertexShaders.java)
|
||||
static const std::string VERTEX_SHADER_SRC = R"""(
|
||||
#version 330 core
|
||||
layout(location = 0) in vec2 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
out vec2 vTexCoord;
|
||||
out vec2 vWorldPos;
|
||||
|
||||
uniform mat3 uModelMatrix;
|
||||
uniform mat3 uViewMatrix;
|
||||
uniform mat3 uProjectionMatrix;
|
||||
|
||||
void main() {
|
||||
// ʹ<><CAB9> 3x3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļλ<C4BB><CEBB>
|
||||
vec3 p = uProjectionMatrix * uViewMatrix * uModelMatrix * vec3(aPosition, 1.0);
|
||||
gl_Position = vec4(p.xy, 0.0, 1.0);
|
||||
vTexCoord = aTexCoord;
|
||||
// <20><><EFBFBD><EFBFBD> world-space λ<>ù<EFBFBD> fragment shader ʹ<>ã<EFBFBD><C3A3><EFBFBD> xy<78><79>
|
||||
vWorldPos = (uModelMatrix * vec3(aPosition, 1.0)).xy;
|
||||
}
|
||||
)""";
|
||||
|
||||
// Ƭ<><C6AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB> GLSL <20><><EFBFBD><EFBFBD> (<28><>Ӧ FragmentShaders.java)
|
||||
static const std::string FRAGMENT_SHADER_SRC = R"""(
|
||||
#version 330 core
|
||||
in vec2 vTexCoord;
|
||||
in vec2 vWorldPos;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec4 uColor;
|
||||
uniform float uOpacity;
|
||||
uniform int uBlendMode;
|
||||
uniform int uDebugMode;
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
uniform vec2 uLightsPos[MAX_LIGHTS];
|
||||
uniform vec3 uLightsColor[MAX_LIGHTS];
|
||||
uniform float uLightsIntensity[MAX_LIGHTS];
|
||||
uniform int uLightsIsAmbient[MAX_LIGHTS];
|
||||
uniform int uLightCount;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>˥<EFBFBD><CBA5>ϵ<EFBFBD><CFB5>
|
||||
const float ATT_CONST = 1.0;
|
||||
const float ATT_LINEAR = 0.09;
|
||||
const float ATT_QUAD = 0.032;
|
||||
|
||||
void main() {
|
||||
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>
|
||||
vec4 tex = texture(uTexture, vTexCoord);
|
||||
float alpha = tex.a * uOpacity;
|
||||
if (alpha <= 0.001) discard;
|
||||
|
||||
// 2. <20><EFBFBD>Դ<EFBFBD>Ż<EFBFBD>·<EFBFBD><C2B7>
|
||||
if (uLightCount == 0) {
|
||||
vec3 base = tex.rgb * uColor.rgb;
|
||||
base = clamp(base, 0.0, 1.0);
|
||||
FragColor = vec4(base, alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. <20><><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>·<EFBFBD><C2B7>
|
||||
vec3 baseColor = tex.rgb * uColor.rgb;
|
||||
vec3 ambient = vec3(0.06); // С<><D0A1><EFBFBD><EFBFBD><EFBFBD>ⲹ<EFBFBD><E2B2B9>
|
||||
vec3 lighting = vec3(0.0);
|
||||
vec3 specularAccum = vec3(0.0);
|
||||
|
||||
// <20>ۻ<EFBFBD><DBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
if (uLightsIsAmbient[i] == 1) {
|
||||
lighting += uLightsColor[i] * uLightsIntensity[i];
|
||||
}
|
||||
}
|
||||
lighting += ambient;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ/<2F>ǻ<EFBFBD><C7BB><EFBFBD><EFBFBD><EFBFBD>
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
if (uLightsIsAmbient[i] == 1) continue;
|
||||
|
||||
vec2 toLight = uLightsPos[i] - vWorldPos;
|
||||
float dist = length(toLight);
|
||||
// <20><>˥<D7BC><CBA5>
|
||||
float attenuation = ATT_CONST / (ATT_CONST + ATT_LINEAR * dist + ATT_QUAD * dist * dist);
|
||||
|
||||
float radiance = uLightsIntensity[i] * attenuation;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
float diffuseFactor = clamp(1.0 - (dist * 0.0015), 0.0, 1.0);
|
||||
vec3 diff = uLightsColor[i] * radiance * diffuseFactor;
|
||||
lighting += diff;
|
||||
|
||||
// <20>߹<F2B5A5B8>
|
||||
vec3 lightDir3 = normalize(vec3(toLight, 0.0));
|
||||
vec3 viewDir = vec3(0.0, 0.0, 1.0);
|
||||
vec3 normal = vec3(0.0, 0.0, 1.0);
|
||||
vec3 reflectDir = reflect(-lightDir3, normal);
|
||||
float specFactor = pow(max(dot(viewDir, reflectDir), 0.0), 16.0);
|
||||
float specIntensity = 0.2;
|
||||
specularAccum += uLightsColor[i] * radiance * specFactor * specIntensity;
|
||||
}
|
||||
|
||||
// Ӧ<>ù<EFBFBD><C3B9><EFBFBD>
|
||||
vec3 totalLighting = min(lighting + specularAccum, vec3(2.0));
|
||||
vec3 finalColor = baseColor * totalLighting;
|
||||
|
||||
// 4. <20><EFBFBD><F2B5A5BB><EFBFBD>ģʽ
|
||||
if (uBlendMode == 1) finalColor = tex.rgb + uColor.rgb;
|
||||
else if (uBlendMode == 2) finalColor = tex.rgb * uColor.rgb;
|
||||
else if (uBlendMode == 3) finalColor = 1.0 - (1.0 - tex.rgb) * (1.0 - uColor.rgb);
|
||||
|
||||
// 5. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
finalColor = clamp(finalColor, 0.0, 1.0);
|
||||
FragColor = vec4(finalColor, alpha);
|
||||
}
|
||||
)""";
|
||||
|
||||
class Shader2D::VertexShaders final : public Shader {
|
||||
public:
|
||||
virtual ~VertexShaders() = default;
|
||||
std::string getShaderCode() const override {
|
||||
return VERTEX_SHADER_SRC;
|
||||
}
|
||||
std::string getShaderName() const override {
|
||||
return "Vertex Shaders";
|
||||
}
|
||||
};
|
||||
|
||||
class Shader2D::FragmentShaders final : public Shader {
|
||||
public:
|
||||
virtual ~FragmentShaders() = default;
|
||||
std::string getShaderCode() const override {
|
||||
return FRAGMENT_SHADER_SRC;
|
||||
}
|
||||
std::string getShaderName() const override {
|
||||
return "Fragment shaders";
|
||||
}
|
||||
};
|
||||
|
||||
const Shader2D::VertexShaders Shader2D::s_vertexShader;
|
||||
const Shader2D::FragmentShaders Shader2D::s_fragmentShader;
|
||||
|
||||
Shader2D::Shader2D()
|
||||
{
|
||||
}
|
||||
|
||||
const Shader& Shader2D::getVertexShader() const
|
||||
{
|
||||
return s_vertexShader;
|
||||
}
|
||||
|
||||
const Shader& Shader2D::getFragmentShader() const
|
||||
{
|
||||
return s_fragmentShader;
|
||||
}
|
||||
|
||||
void Shader2D::setDefaultUniforms(ShaderProgram* program) const
|
||||
{
|
||||
}
|
||||
33
Vivid2DRenderer/systems/sources/def/Shader2D.h
Normal file
33
Vivid2DRenderer/systems/sources/def/Shader2D.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#include "../CompleteShader.h"
|
||||
#include "../ShaderProgram.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
/**
|
||||
* @brief Ĭ<><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>ʵ<EFBFBD><CAB5> (Shader2D)
|
||||
* <20>̳<EFBFBD><CCB3><EFBFBD> CompleteShader<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2D <20><>Ⱦ<EFBFBD><C8BE>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
||||
*/
|
||||
class Shader2D final : public CompleteShader {
|
||||
public:
|
||||
Shader2D();
|
||||
virtual ~Shader2D() = default;
|
||||
const Shader& getVertexShader() const override;
|
||||
const Shader& getFragmentShader() const override;
|
||||
std::string getShaderName() const override {
|
||||
return "Vivid2d Shader";
|
||||
}
|
||||
bool isDefaultShader() const override {
|
||||
return true;
|
||||
}
|
||||
void setDefaultUniforms(ShaderProgram* program) const override;
|
||||
private:
|
||||
// <20>ڲ<EFBFBD><DAB2><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> .cpp <20>ļ<EFBFBD><C4BC>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
class VertexShaders;
|
||||
class FragmentShaders;
|
||||
|
||||
// <20><>̬<EFBFBD><CCAC>Ա<EFBFBD>洢<EFBFBD><E6B4A2>ɫ<EFBFBD><C9AB>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ð<EFBFBD>ȫ
|
||||
static const VertexShaders s_vertexShader;
|
||||
static const FragmentShaders s_fragmentShader;
|
||||
};
|
||||
123
Vivid2DRenderer/systems/sources/def/SolidColorShader.cpp
Normal file
123
Vivid2DRenderer/systems/sources/def/SolidColorShader.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "SolidColorShader.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
static const std::string SOLID_COLOR_VERTEX_SHADER_SRC = R"""(
|
||||
#version 330 core
|
||||
layout(location = 0) in vec2 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
|
||||
uniform mat3 uModelMatrix;
|
||||
uniform mat3 uViewMatrix;
|
||||
uniform mat3 uProjectionMatrix;
|
||||
|
||||
void main() {
|
||||
// ʹ<><CAB9> 3x3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļλ<C4BB><CEBB>
|
||||
vec3 p = uProjectionMatrix * uViewMatrix * uModelMatrix * vec3(aPosition, 1.0);
|
||||
gl_Position = vec4(p.xy, 0.0, 1.0);
|
||||
}
|
||||
)""";
|
||||
|
||||
static const std::string SOLID_COLOR_FRAGMENT_SHADER_SRC = R"""(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform vec4 uColor;
|
||||
uniform float uOpacity;
|
||||
|
||||
void main() {
|
||||
// ֱ<><D6B1>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
vec4 finalColor = uColor;
|
||||
finalColor.a *= uOpacity;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>̫<EFBFBD><CCAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC>
|
||||
if (finalColor.a <= 0.001) discard;
|
||||
|
||||
FragColor = finalColor;
|
||||
}
|
||||
)""";
|
||||
|
||||
class SolidColorShader::SolidColorVertexShader final : public Shader {
|
||||
public:
|
||||
virtual ~SolidColorVertexShader() = default;
|
||||
std::string getShaderCode() const override {
|
||||
return SOLID_COLOR_VERTEX_SHADER_SRC;
|
||||
}
|
||||
std::string getShaderName() const override {
|
||||
return "Solid Color Vertex Shader";
|
||||
}
|
||||
};
|
||||
|
||||
class SolidColorShader::SolidColorFragmentShader final : public Shader {
|
||||
public:
|
||||
virtual ~SolidColorFragmentShader() = default;
|
||||
std::string getShaderCode() const override {
|
||||
return SOLID_COLOR_FRAGMENT_SHADER_SRC;
|
||||
}
|
||||
std::string getShaderName() const override {
|
||||
return "Solid Color Fragment Shader";
|
||||
}
|
||||
};
|
||||
|
||||
const SolidColorShader::SolidColorVertexShader SolidColorShader::s_vertexShader;
|
||||
const SolidColorShader::SolidColorFragmentShader SolidColorShader::s_fragmentShader;
|
||||
|
||||
SolidColorShader::SolidColorShader()
|
||||
{
|
||||
}
|
||||
|
||||
const Shader& SolidColorShader::getVertexShader() const
|
||||
{
|
||||
return s_vertexShader;
|
||||
}
|
||||
|
||||
const Shader& SolidColorShader::getFragmentShader() const
|
||||
{
|
||||
return s_fragmentShader;
|
||||
}
|
||||
|
||||
void SolidColorShader::setDefaultUniforms(ShaderProgram* program) const
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
int colorLoc = program->getUniformLocation("uColor");
|
||||
if (colorLoc != -1) {
|
||||
program->setUniform4f(colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
int opacityLoc = program->getUniformLocation("uOpacity");
|
||||
if (opacityLoc != -1) {
|
||||
program->setUniform1f(opacityLoc, 1.0f);
|
||||
}
|
||||
|
||||
program->stop();
|
||||
}
|
||||
|
||||
void SolidColorShader::setColor(ShaderProgram* program, float r, float g, float b, float a)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
|
||||
int colorLoc = program->getUniformLocation("uColor");
|
||||
if (colorLoc != -1) {
|
||||
program->setUniform4f(colorLoc, r, g, b, a);
|
||||
}
|
||||
|
||||
program->stop();
|
||||
}
|
||||
|
||||
void SolidColorShader::setOpacity(ShaderProgram* program, float opacity)
|
||||
{
|
||||
if (!program) return;
|
||||
|
||||
program->use();
|
||||
|
||||
int opacityLoc = program->getUniformLocation("uOpacity");
|
||||
if (opacityLoc != -1) {
|
||||
program->setUniform1f(opacityLoc, opacity);
|
||||
}
|
||||
|
||||
program->stop();
|
||||
}
|
||||
59
Vivid2DRenderer/systems/sources/def/SolidColorShader.h
Normal file
59
Vivid2DRenderer/systems/sources/def/SolidColorShader.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include "../CompleteShader.h"
|
||||
#include "../ShaderProgram.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
/**
|
||||
* @brief <20><>ɫ<EFBFBD><C9AB>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (SolidColorShader)
|
||||
* ר<><D7A8><EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD><DABB>ƴ<EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>壬<EFBFBD><E5A3AC>ѡ<EFBFBD>п<D0BF><F2A1A2B5><EFBFBD>ͼ<EFBFBD>εȡ<CEB5>
|
||||
*/
|
||||
class SolidColorShader final : public CompleteShader {
|
||||
public:
|
||||
SolidColorShader();
|
||||
virtual ~SolidColorShader() = default;
|
||||
|
||||
// --- CompleteShader <20>ӿ<EFBFBD>ʵ<EFBFBD><CAB5> ---
|
||||
|
||||
// <20><><EFBFBD>뷵<EFBFBD><EBB7B5> const <20><><EFBFBD><EFBFBD>
|
||||
const Shader& getVertexShader() const override;
|
||||
|
||||
// <20><><EFBFBD>뷵<EFBFBD><EBB7B5> const <20><><EFBFBD><EFBFBD>
|
||||
const Shader& getFragmentShader() const override;
|
||||
|
||||
std::string getShaderName() const override {
|
||||
return "Solid Color Shader";
|
||||
}
|
||||
|
||||
bool isDefaultShader() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> const <20><>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>
|
||||
void setDefaultUniforms(ShaderProgram* program) const override;
|
||||
|
||||
// --- <20><>ɫ/<2F><><EFBFBD><CDB8><EFBFBD>ȿ<EFBFBD><C8BF>Ʒ<EFBFBD><C6B7><EFBFBD> ---
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>ɫ
|
||||
* @param program <20><>ǰʹ<C7B0>õ<EFBFBD><C3B5><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param r, g, b, a <20><>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void setColor(ShaderProgram* program, float r, float g, float b, float a);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>
|
||||
* @param program <20><>ǰʹ<C7B0>õ<EFBFBD><C3B5><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param opacity <20><><EFBFBD><CDB8><EFBFBD><EFBFBD>ֵ
|
||||
*/
|
||||
void setOpacity(ShaderProgram* program, float opacity);
|
||||
|
||||
private:
|
||||
// <20>ڲ<EFBFBD><DAB2><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> .cpp <20>ļ<EFBFBD><C4BC>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
class SolidColorVertexShader;
|
||||
class SolidColorFragmentShader;
|
||||
|
||||
// <20><>̬<EFBFBD><CCAC>Ա<EFBFBD>洢<EFBFBD><E6B4A2>ɫ<EFBFBD><C9AB>ʵ<EFBFBD><CAB5>
|
||||
static const SolidColorVertexShader s_vertexShader;
|
||||
static const SolidColorFragmentShader s_fragmentShader;
|
||||
};
|
||||
78
Vivid2DRenderer/systems/sources/def/TextShader.cpp
Normal file
78
Vivid2DRenderer/systems/sources/def/TextShader.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "TextShader.h"
|
||||
|
||||
#include "../ShaderProgram.h"
|
||||
|
||||
static const std::string TEXT_VERTEX_SHADER_CODE = R"""(
|
||||
#version 330 core
|
||||
layout(location = 0) in vec2 aPosition;
|
||||
layout(location = 1) in vec2 aTexCoord;
|
||||
|
||||
uniform mat3 uProjectionMatrix;
|
||||
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vec3 p = uProjectionMatrix * vec3(aPosition, 1.0);
|
||||
gl_Position = vec4(p.xy, 0.0, 1.0);
|
||||
vTexCoord = aTexCoord;
|
||||
}
|
||||
)""";
|
||||
|
||||
static const std::string TEXT_FRAGMENT_SHADER_CODE = R"""(
|
||||
#version 330 core
|
||||
in vec2 vTexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec4 uColor;
|
||||
|
||||
void main() {
|
||||
// ʹ<><CAB9> .r ͨ<><CDA8><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λͼ)
|
||||
float alpha = texture(uTexture, vTexCoord).r;
|
||||
FragColor = vec4(uColor.rgb, uColor.a * alpha);
|
||||
}
|
||||
)""";
|
||||
|
||||
class TextShader::TextVertexShader : public Shader {
|
||||
public:
|
||||
virtual ~TextVertexShader() = default;
|
||||
std::string getShaderCode() const override { return TEXT_VERTEX_SHADER_CODE; }
|
||||
std::string getShaderName() const override { return "TextVertexShader"; }
|
||||
};
|
||||
class TextShader::TextFragmentShader : public Shader {
|
||||
public:
|
||||
virtual ~TextFragmentShader() = default;
|
||||
std::string getShaderCode() const override { return TEXT_FRAGMENT_SHADER_CODE; }
|
||||
std::string getShaderName() const override { return "TextFragmentShader"; }
|
||||
};
|
||||
const TextShader::TextVertexShader TextShader::s_vertexShader;
|
||||
const TextShader::TextFragmentShader TextShader::s_fragmentShader;
|
||||
TextShader::TextShader()
|
||||
: m_color(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
{}
|
||||
|
||||
const Shader& TextShader::getVertexShader() const
|
||||
{
|
||||
return s_vertexShader;
|
||||
}
|
||||
|
||||
const Shader& TextShader::getFragmentShader() const
|
||||
{
|
||||
return s_fragmentShader;
|
||||
}
|
||||
|
||||
void TextShader::setColor(const glm::vec4& color)
|
||||
{
|
||||
this->m_color = color;
|
||||
}
|
||||
|
||||
void TextShader::setDefaultUniforms(ShaderProgram* program)
|
||||
{
|
||||
if (!program) return;
|
||||
program->use();
|
||||
program->setUniform4f("uColor", m_color.r, m_color.g, m_color.b, m_color.a);
|
||||
program->setUniform1i("uTexture", 0);
|
||||
program->stop();
|
||||
}
|
||||
58
Vivid2DRenderer/systems/sources/def/TextShader.h
Normal file
58
Vivid2DRenderer/systems/sources/def/TextShader.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
// TextShader.h <20><> .../systems/sources/def
|
||||
#include "../CompleteShader.h"
|
||||
#include "../Shader.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class ShaderProgram;
|
||||
|
||||
/**
|
||||
* @brief <20>ı<EFBFBD><C4B1><EFBFBD>ɫ<EFBFBD><C9AB> (TextShader)
|
||||
* <20>̳<EFBFBD><CCB3><EFBFBD> CompleteShader<65><72><EFBFBD>ṩ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>á<EFBFBD>
|
||||
*/
|
||||
class TextShader : public CompleteShader {
|
||||
public:
|
||||
TextShader();
|
||||
virtual ~TextShader() = default;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||||
*/
|
||||
std::string getShaderName() const override { return "TextShader"; }
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>塣
|
||||
*/
|
||||
const Shader& getVertexShader() const override;
|
||||
|
||||
/**
|
||||
* @brief <20><>ȡƬ<C8A1><C6AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD>塣
|
||||
*/
|
||||
const Shader& getFragmentShader() const override;
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void setDefaultUniforms(ShaderProgram* program);
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>ɫ<EFBFBD><C9AB>
|
||||
*/
|
||||
void setColor(const glm::vec4& color);
|
||||
|
||||
/**
|
||||
* @brief <20>Ƿ<EFBFBD>ΪĬ<CEAA><C4AC><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>
|
||||
*/
|
||||
bool isDefaultShader() const override { return false; }
|
||||
|
||||
private:
|
||||
glm::vec4 m_color;
|
||||
|
||||
// <20><>̬<EFBFBD><CCAC>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><DAB7>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>
|
||||
class TextVertexShader;
|
||||
class TextFragmentShader;
|
||||
|
||||
static const TextVertexShader s_vertexShader;
|
||||
static const TextFragmentShader s_fragmentShader;
|
||||
};
|
||||
7
Vivid2DRenderer/vcpkg.json
Normal file
7
Vivid2DRenderer/vcpkg.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "my-opengl-project",
|
||||
"version-string": "0.1.0",
|
||||
"dependencies": [
|
||||
"stb"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user