New initial commit with reorganized structer

This commit is contained in:
dean11 2013-11-06 22:52:00 +01:00
parent 94c1ae23f1
commit 9ee656d270
124 changed files with 14110 additions and 0 deletions

165
DanBias.sln Normal file
View File

@ -0,0 +1,165 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterGraphics", "OysterGraphics\OysterGraphics.vcxproj", "{0EC83E64-230E-48EF-B08C-6AC9651B4F82}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterMath", "OysterMath\OysterMath.vcxproj", "{F10CBC03-9809-4CBA-95D8-327C287B18EE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterPhysics3D", "OysterPhysics3D\OysterPhysics3D.vcxproj", "{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sound", "Sound\Sound.vcxproj", "{34D6295A-00DD-4B1A-8258-97DA2818EC26}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowManager", "WindowManager\WindowManager.vcxproj", "{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Input", "Input\Input.vcxproj", "{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Misc", "Misc\Misc.vcxproj", "{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Network", "Network", "{C27B926E-B3EF-4990-8822-47580E43A0BE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterNetworkClient", "Network\OysterNetworkClient\OysterNetworkClient.vcxproj", "{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterNetworkServer", "Network\OysterNetworkServer\OysterNetworkServer.vcxproj", "{6A066806-F43F-4B31-A4E3-57179674F460}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetworkDependencies", "Network\NetworkDependencies\NetworkDependencies.vcxproj", "{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.ActiveCfg = Debug|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.Build.0 = Debug|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.ActiveCfg = Debug|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.Build.0 = Debug|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.ActiveCfg = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.Build.0 = Release|Win32
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.ActiveCfg = Release|x64
{0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.Build.0 = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.ActiveCfg = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.Build.0 = Debug|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.ActiveCfg = Debug|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.Build.0 = Debug|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.ActiveCfg = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.Build.0 = Release|Win32
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.ActiveCfg = Release|x64
{F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.Build.0 = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.ActiveCfg = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.Build.0 = Debug|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.ActiveCfg = Debug|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.Build.0 = Debug|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.ActiveCfg = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.Build.0 = Release|Win32
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.ActiveCfg = Release|x64
{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.Build.0 = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.ActiveCfg = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.Build.0 = Debug|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.ActiveCfg = Debug|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.Build.0 = Debug|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.ActiveCfg = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.Build.0 = Release|Win32
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.ActiveCfg = Release|x64
{34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.Build.0 = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.ActiveCfg = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.Build.0 = Debug|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.ActiveCfg = Debug|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.Build.0 = Debug|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.ActiveCfg = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.Build.0 = Release|Win32
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.ActiveCfg = Release|x64
{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.Build.0 = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.ActiveCfg = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.Build.0 = Debug|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.ActiveCfg = Debug|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.Build.0 = Debug|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.ActiveCfg = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.Build.0 = Release|Win32
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.ActiveCfg = Release|x64
{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.Build.0 = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.ActiveCfg = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.Build.0 = Debug|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.ActiveCfg = Debug|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.Build.0 = Debug|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.ActiveCfg = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.Build.0 = Release|Win32
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.ActiveCfg = Release|x64
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.Build.0 = Release|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.ActiveCfg = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.Build.0 = Debug|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.ActiveCfg = Debug|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.Build.0 = Debug|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.Build.0 = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.ActiveCfg = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.Build.0 = Release|Win32
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.ActiveCfg = Release|x64
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.Build.0 = Release|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.ActiveCfg = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.Build.0 = Debug|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.ActiveCfg = Debug|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.Build.0 = Debug|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.Build.0 = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.ActiveCfg = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.Build.0 = Release|Win32
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.ActiveCfg = Release|x64
{6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.Build.0 = Release|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.ActiveCfg = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.Build.0 = Debug|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.ActiveCfg = Debug|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.Build.0 = Debug|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.Build.0 = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.ActiveCfg = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.Build.0 = Release|Win32
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.ActiveCfg = Release|x64
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
{6A066806-F43F-4B31-A4E3-57179674F460} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,428 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<diagram program="umlet" version="12.1">
<zoom_level>9</zoom_level>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>675</x>
<y>342</y>
<w>108</w>
<h>27</h>
</coordinates>
<panel_attributes>Graphics</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>441</x>
<y>342</y>
<w>108</w>
<h>27</h>
</coordinates>
<panel_attributes>Sound</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>531</x>
<y>279</y>
<w>108</w>
<h>27</h>
</coordinates>
<panel_attributes>Physics / Math</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>684</x>
<y>153</y>
<w>99</w>
<h>27</h>
</coordinates>
<panel_attributes>Game client</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>351</x>
<y>279</y>
<w>126</w>
<h>27</h>
</coordinates>
<panel_attributes>Gamelogic</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>369</x>
<y>153</y>
<w>99</w>
<h>27</h>
</coordinates>
<panel_attributes>Game server</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>531</x>
<y>207</y>
<w>108</w>
<h>27</h>
</coordinates>
<panel_attributes>Network</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>558</x>
<y>342</y>
<w>108</w>
<h>27</h>
</coordinates>
<panel_attributes>Input</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>531</x>
<y>243</y>
<w>108</w>
<h>27</h>
</coordinates>
<panel_attributes>Threading</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>531</x>
<y>90</y>
<w>108</w>
<h>36</h>
</coordinates>
<panel_attributes>DanBias
bg=green</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>702</x>
<y>153</y>
<w>44</w>
<h>206</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;189;27;171;27;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>459</x>
<y>153</y>
<w>287</w>
<h>206</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;189;27;171;270;171;270;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>387</x>
<y>153</y>
<w>44</w>
<h>143</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;126;27;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>612</x>
<y>153</y>
<w>134</w>
<h>152</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;135;117;135;117;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>387</x>
<y>153</y>
<w>161</w>
<h>80</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>144;63;27;63;27;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>450</x>
<y>261</y>
<w>98</w>
<h>44</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>81;27;27;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>585</x>
<y>153</y>
<w>161</w>
<h>206</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;189;27;171;144;171;144;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>387</x>
<y>153</y>
<w>161</w>
<h>116</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>144;99;27;99;27;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>612</x>
<y>153</y>
<w>134</w>
<h>116</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;99;117;99;117;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>612</x>
<y>153</y>
<w>134</w>
<h>80</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;63;117;63;117;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>612</x>
<y>72</y>
<w>134</w>
<h>98</h>
</coordinates>
<panel_attributes>lt=&gt;-</panel_attributes>
<additional_attributes>27;27;117;27;117;81</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>387</x>
<y>72</y>
<w>161</w>
<h>98</h>
</coordinates>
<panel_attributes>lt=&gt;-</panel_attributes>
<additional_attributes>144;27;27;27;27;81</additional_attributes>
</element>
<element>
<type>com.umlet.element.Package</type>
<coordinates>
<x>342</x>
<y>54</y>
<w>450</w>
<h>333</h>
</coordinates>
<panel_attributes>Game</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>702</x>
<y>342</y>
<w>44</w>
<h>134</h>
</coordinates>
<panel_attributes>lt=&lt;&lt;.</panel_attributes>
<additional_attributes>27;27;27;117</additional_attributes>
</element>
<element>
<type>com.umlet.element.Package</type>
<coordinates>
<x>711</x>
<y>459</y>
<w>261</w>
<h>180</h>
</coordinates>
<panel_attributes>Graphics</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>720</x>
<y>486</y>
<w>243</w>
<h>144</h>
</coordinates>
<panel_attributes>&lt;&lt;interface&gt;&gt;
OysterGfx
--
Init(InitData :struct) :enum state
NewFrame(FrameConstant :struct) :void
GatherData(Model :struct) :void
Render() :void
SetOptions(Options :struct) :void
LoadModel(file :const wchar[]) :Model*
Release(resource :Model*) :void</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Package</type>
<coordinates>
<x>441</x>
<y>459</y>
<w>252</w>
<h>198</h>
</coordinates>
<panel_attributes>Input</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>513</x>
<y>342</y>
<w>116</w>
<h>143</h>
</coordinates>
<panel_attributes>lt=&lt;&lt;.</panel_attributes>
<additional_attributes>99;27;99;126;27;126</additional_attributes>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>450</x>
<y>486</y>
<w>234</w>
<h>162</h>
</coordinates>
<panel_attributes>&lt;&lt;interface&gt;&gt;
RawInput
--
Self() :RawInput*
Destroy() :void
QueryInput(Key :enum state(RIK)) :void
Subscribe(Callback :function) :void
Unsubscribe(Calback :function) :void
GetError() const :const wchar*
AddDevice(Data :struct) :enum state
Enable(Enable :bool) :void</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>351</x>
<y>342</y>
<w>81</w>
<h>27</h>
</coordinates>
<panel_attributes>Window API</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>360</x>
<y>153</y>
<w>386</w>
<h>206</h>
</coordinates>
<panel_attributes>lt=&lt;-</panel_attributes>
<additional_attributes>27;189;27;171;369;171;369;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Package</type>
<coordinates>
<x>126</x>
<y>459</y>
<w>306</w>
<h>198</h>
</coordinates>
<panel_attributes>Sound</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>135</x>
<y>486</y>
<w>288</w>
<h>99</h>
</coordinates>
<panel_attributes>&lt;&lt;interface&gt;&gt;
SoundWrapper
--
LoadResource(file :const char*) :ResoureHandle*
Play(PlayData :struct) :InstanceID
Stop(InstanceID :int) :void
Release(Resource :ResourceHandle*) :void</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Class</type>
<coordinates>
<x>135</x>
<y>612</y>
<w>288</w>
<h>36</h>
</coordinates>
<panel_attributes>&lt;&lt;API&gt;&gt;
--
FMOD</panel_attributes>
<additional_attributes/>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>252</x>
<y>558</y>
<w>44</w>
<h>71</h>
</coordinates>
<panel_attributes>lt=&lt;&lt;.</panel_attributes>
<additional_attributes>27;54;27;27</additional_attributes>
</element>
<element>
<type>com.umlet.element.Relation</type>
<coordinates>
<x>216</x>
<y>342</y>
<w>296</w>
<h>143</h>
</coordinates>
<panel_attributes>lt=&lt;&lt;.</panel_attributes>
<additional_attributes>279;27;279;72;207;72;207;126;27;126</additional_attributes>
</element>
</diagram>

View File

@ -0,0 +1,16 @@
float3 func( in float3 normalA, in float3 normalB, in float3 normalC )
{
return normalize( lerp( lerp(normalA, normalB, 0.5f), lerp(normalA, normalC, 0.5f), 0.5f ) );
}
float3 nearTopLeft = func( f.topPlane.normal, f.leftPlane.normal, f.nearPlane.normal );
float3 nearTopRight = func( f.topPlane.normal, f.rightPlane.normal, f.nearPlane.normal );
float3 nearBottomLeft = func( f.bottomPlane.normal, f.leftPlane.normal, f.nearPlane.normal );
float3 nearBottomRight = func( f.bottomPlane.normal, f.rightPlane.normal, f.nearPlane.normal );
float3 farTopLeft = func( f.topPlane.normal, f.leftPlane.normal, f.farPlane.normal );
float3 farTopRight = func( f.topPlane.normal, f.rightPlane.normal, f.farPlane.normal );
float3 farBottomLeft = func( f.bottomPlane.normal, f.leftPlane.normal, f.farPlane.normal );
float3 farBottomRight = func( f.bottomPlane.normal, f.rightPlane.normal, f.farPlane.normal );

View File

@ -0,0 +1,193 @@
#include"RawInput.h"
//DefRawInputProc
//GetRawInputDeviceList
//GetRegisteredRawInputDevices
LRESULT CALLBACK RawInput::WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lparam)
{
if (nCode < 0) return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam);
MSG *m = (MSG*)lparam;
if(m->message == WM_INPUT)
{
RAWINPUT* raw = RawInput::Self()->_TranslateRawInput(m->lParam);
if(!raw) goto nextHook;
if(!RawInput::Self()->Self()->_enabled)
{
if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) )
RawInput::Self()->_errorMsg = L"Failed to proccess default raw input";
goto _final;
}
// if(raw->header.dwType == RIM_TYPEMOUSE) RawInput::Self()->_idleMouseData.insert(raw->data.mouse);
//else if(raw->header.dwType == RIM_TYPEKEYBOARD) RawInput::Self()->_proccessRawKeyboardData(raw->data.keyboard);
_final:
//if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) )
// RawInput::Self()->_errorMsg = L"Failed to proccess default raw input";
delete raw;
}
else if (m->message == WM_QUIT)
{
if(UnhookWindowsHookEx(RawInput::Self()->_msgHook) == FALSE)
{
RawInput::Self()->_errorMsg = L"Failed to unhook message hook!";
}
}
nextHook:
return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam);
}
RAWINPUT* RawInput::_TranslateRawInput (LPARAM l)
{
//Get The size of the raw data buffer
UINT bufferSize;
GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
if (bufferSize < 1)
{
//Something went wrong
RawInput::Self()->_errorMsg = L"Failed to read raw buffer data in input class";
return 0;
}
//Create and read the raw input data
LPBYTE rawBufferIn = new BYTE[bufferSize];
UINT readBytes = GetRawInputData((HRAWINPUT)l, RID_INPUT, rawBufferIn, &bufferSize, sizeof(RAWINPUTHEADER));
if ( readBytes != bufferSize )
{
RawInput::Self()->_errorMsg = L"Could not read raw input data";
delete [] rawBufferIn;
return 0;
}
return (RAWINPUT*)rawBufferIn;
}
void RawInput::_proccessRawKeyboardData (RAWKEYBOARD& k)
{
if(!this->_KeyboardEnabled) return;
//The key is released.
if(k.Flags == RI_KEY_BREAK || k.Flags == (RI_KEY_BREAK | RI_KEY_E0) || k.Flags == (RI_KEY_BREAK | RI_KEY_E1))
{
if(k.Message == WM_SYSKEYUP)
{
// if(k.VKey == VK_CONTROL) this->_procCollection.skd.ctrl = false;
//else if(k.VKey == VK_MENU) this->_procCollection.skd.alt = false;
//else if(k.VKey == VK_SHIFT) this->_procCollection.skd.shift = false;
}
else if(k.Message == WM_KEYUP)
{
//this->_procCollection.kd.key = (RIK)k.VKey;
//this->_procCollection.kd.released = true;
}
}
//The key is pressed.
else if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))
{
if(k.Message == WM_SYSKEYDOWN)
{
// if(k.VKey == VK_CONTROL) this->_procCollection.skd.ctrl = true;
//else if(k.VKey == VK_MENU) this->_procCollection.skd.alt = true;
//else if(k.VKey == VK_SHIFT) this->_procCollection.skd.shift = true;
}
else if(k.Message == WM_KEYDOWN)
{
//this->_procCollection.kd.key = (RIK)k.VKey;
//this->_procCollection.kd.released = false;
}
}
}
void RawInput::_proccessRawMouseData (RAWMOUSE& m)
{
if(!this->_mouseEnabled) return;
if(m.lLastX != 0 || m.lLastY != 0)
{
//this->_procCollection.mmd.MousePos_X += m.lLastX;
//this->_procCollection.mmd.MousePos_Y += m.lLastY;
}
if( m.usButtonFlags > 0 )
{
switch (m.usButtonFlags)
{
//Mouse button pressed
case RI_MOUSE_LEFT_BUTTON_DOWN:
case RI_MOUSE_RIGHT_BUTTON_DOWN:
case RI_MOUSE_MIDDLE_BUTTON_DOWN:
{
if(m.usButtonFlags == RI_MOUSE_LEFT_BUTTON_DOWN)
{
//MOUSE_INPUT_btnData.key = RIK_LeftBtn;
//LBTNDOWN = true;
}
else if(m.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_DOWN)
{
//MOUSE_INPUT_btnData.key = RIK_MiddleBtn;
//MBTNDOWN = true;
}
else if(m.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_DOWN)
{
//MOUSE_INPUT_btnData.key = RIK_RightBtn;
//RBTNDOWN = true;
}
}
break;
//Mouse button Released
case RI_MOUSE_LEFT_BUTTON_UP:
case RI_MOUSE_RIGHT_BUTTON_UP:
case RI_MOUSE_MIDDLE_BUTTON_UP:
{
if(m.usButtonFlags == RI_MOUSE_LEFT_BUTTON_UP)
{
//MOUSE_INPUT_btnData.key = RIK_LeftBtn;
//LBTNDOWN = false;
}
else if(m.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_UP)
{
//MOUSE_INPUT_btnData.key = RIK_MiddleBtn;
//MBTNDOWN = false;
}
else if(m.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_UP)
{
//MOUSE_INPUT_btnData.key = RIK_RightBtn;
//RBTNDOWN = false;
}
}
break;
case RI_MOUSE_WHEEL:
{
int d = ((int)m.usButtonData);
if(d > 120) d = -1;
else d = 1;
//this->_procCollection.wd = d;
}
break;
}
}
}

View File

@ -0,0 +1,57 @@
#include "RawInput.h"
void RawInput::Mouse_Show()
{
}
void RawInput::Mouse_Hide()
{
}
void RawInput::Mouse_Lock()
{
}
void RawInput::Mouse_Unlock()
{
}
void RawInput::Mouse_IsBtnPressed(IN RIK)
{
}
int RawInput::Mouse_WheelDelta()
{
return 0;
}
POINT RawInput::Mouse_Position()
{
POINT p = {0, 0};
//POINT p = { this->_activeInputData.data.MOUSE_DATA.MousePos_X, this->_activeInputData.data.MOUSE_DATA.MousePos_Y };
return p;
}
void RawInput::Mouse_Enable()
{
this->_mouseEnabled = true;
}
void RawInput::Mouse_Disable()
{
this->_mouseEnabled = false;
}
bool RawInput::Keyboard_KeyUp(IN RIK key)
{
return false;
}
bool RawInput::Keyboard_KeyDown(IN RIK key)
{
return false;
}
void RawInput::Keyboard_Enable()
{
this->_KeyboardEnabled = true;
}
void RawInput::Keyboard_Disable()
{
this->_KeyboardEnabled = false;
}

View File

@ -0,0 +1,142 @@
#include "RawInput.h"
template<typename FNC, typename PARAM, typename OBJECT_PARAM>
void SUBSCRIBE(SubscribeList<FNC, PARAM>* l, FNC _fnc, OBJECT_PARAM p)
{
SubscribeList<FNC, PARAM>* t = new SubscribeList<FNC, PARAM>();
t->param = p;
t->fnc = _fnc;
t->next = l;
l = t;
}
template<typename FNC, typename PARAM>
void UNSUBSCRIBE(SubscribeList<FNC, PARAM>* l, FNC fnc)
{
SubscribeList<FNC, PARAM>* w = l;
SubscribeList<FNC, PARAM>* p = 0;
while (w)
{
if(w->fnc == fnc)
{
if(p)
p->next = w->next;
delete w;
w = 0;
}
else
{
p = w;
w = w->next;
}
}
}
void RawInput::Input_Subscribe (IN INPUT_CALLBACK fnc)
{
//SUBSCRIBE(this->_procInput, fnc, &this->_procCollection.id);
}
void RawInput::Input_Unsubscribe (IN INPUT_CALLBACK fnc)
{
//UNSUBSCRIBE(this->_procSystemKey, fnc);
}
/*
void RawInput::Subscribe (RAW_KEY_PROC fnc)
{
KeyboardProcList* t = new KeyboardProcList();
t->fnc = fnc;
t->next = 0;
KeyboardProcList* w = this->_keyProcList;
KeyboardProcList* prev = this->_keyProcList;
while (w)
{
prev = w;
w = w->next;
}
prev->next = t;
}
void RawInput::Subscribe (RAW_MOUSE_PROC fnc)
{
MouseProcList* t = new MouseProcList();
t->fnc = fnc;
t->next = 0;
MouseProcList* w = this->_mouseProcList;
MouseProcList* prev = this->_mouseProcList;
while (w)
{
prev = w;
w = w->next;
}
prev->next = t;
}
void RawInput::Unsubscribe (RAW_KEY_PROC fnc)
{
KeyboardProcList* w = this->_keyProcList;
KeyboardProcList* prev = 0;
while (w)
{
if(w->fnc == fnc)
{
if(prev)
prev->next = w->next;
delete w;
w = 0;
}
else
{
prev = w;
w = w->next;
}
}
}
void RawInput::Unsubscribe (RAW_MOUSE_PROC fnc)
{
MouseProcList* w = this->_mouseProcList;
MouseProcList* prev = 0;
while (w)
{
if(w->fnc == fnc)
{
if(prev)
prev->next = w->next;
delete w;
w = 0;
}
else
{
prev = w;
w = w->next;
}
}
}
*/

View File

@ -0,0 +1,182 @@
#include "RawInput.h"
#include <WindowsX.h>
#include <algorithm>
#include <ctime>
#include <fstream>
#include <iostream>
static RawInput* gInstance = 0;
template<typename FNC, typename PARAM> void DESTROY_LIST(SubscribeList<FNC, PARAM>* l)
{
SubscribeList<FNC, PARAM>* w = l;
SubscribeList<FNC, PARAM>* p = 0;
while (w)
{
p = w;
w = w->next;
delete p;
}
}
template<typename FNC, typename PARAM> void PROCESS_SUBSCRIBERS(SubscribeList<FNC, PARAM>* l)
{
while (l)
{
l->fnc(l->param);
l = l->next;
}
}
RawInputWrapper* RawInputWrapper::Self ()
{
return (RawInputWrapper*)RawInput::Self();
}
void RawInputWrapper::Destroy ()
{
RawInput::Destroy();
}
RawInput* RawInput::Self ()
{
if(!gInstance)
gInstance = new RawInput();
return gInstance;
}
void RawInput::Destroy ()
{
/************************ Delete subscribers ****************************/
DESTROY_LIST(RawInput::Self()->_procInput);
/************************ Delete Other stuff ****************************/
ShowCursor(true);
RECT r;
GetWindowRect(GetDesktopWindow(), &r);
ClipCursor(&r);
/************************ Delete instance ****************************/
delete gInstance;
gInstance = NULL;
}
RawInput::RawInput ()
: _procInput(0)
, _enabled(1)
, _mouseEnabled(1)
, _KeyboardEnabled(1)
, _exclusive(0)
, _errorMsg(0)
, _msgHook(SetWindowsHookEx(WH_GETMESSAGE, WM_INPUT_TRANSLATE, (HINSTANCE)0, GetCurrentThreadId()))
{
if(!_msgHook) this->_errorMsg = L"Failed to initiate window message hook";
}
RawInput::~RawInput ()
{}
const wchar_t* RawInput::Input_GetError() const
{
return this->_errorMsg;
}
bool RawInput::Input_AddDevice(IN const HWND& targetApplication)
{
assert(targetApplication != 0);
static const UINT c = 2;
RAWINPUTDEVICE devices[c] =
{
{ 0x01, RawInput_Usage_keyboard, RIDEV_NOLEGACY, targetApplication },
{ 0x01, RawInput_Usage_mouse, RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE, targetApplication }
};
if(! _addDevice( devices , c ) ) return false;
ShowCursor(FALSE);
//RECT r;
//GetWindow
//GetWindowRect(
return true;
}
bool RawInput::Input_AddDevice(IN const RAWINPUTDEVICE* d, const int& count)
{
for (int i = 0; i < count; i++)
if(!d[i].hwndTarget)
{
this->_errorMsg = L"Must specify target application";
return false;
}
if(! _addDevice( d, count ) ) return false;
return true;
}
//RAWINPUTDEVICE d = { 0x01, type, RIDEV_REMOVE, NULL };
//this->_errorMsg = L"Failed to unregister device";
void RawInput::Input_Disable()
{
this->_enabled = false;
}
void RawInput::Input_Enable()
{
this->_enabled = true;
}
void RawInput::Input_Read()
{
//for (int i = 0; i < this->_idleKeyData.size(); i++)
// this->_proccessRawKeyboardData(this->_idleKeyData.pop());
//for (int i = 0; i < this->_idleMouseData.size(); i++)
// this->_proccessRawMouseData(this->_idleMouseData.pop());
//
//this->_idleKeyData.clear();
//this->_idleMouseData.clear();
}
bool RawInput::_addDevice (const RAWINPUTDEVICE* k, const int& count)
{
if(RegisterRawInputDevices(k, count, sizeof(RAWINPUTDEVICE)) == FALSE)
{
DWORD h = GetLastError();
this->_errorMsg = L"Failed to register device";
return false;
}
for (int q = 0; q < count; q++)
{
RawInputDeviceInstance i;
memcpy(&i.description, &k[q], sizeof(RAWINPUTDEVICE));
this->_deviceList.push(i);
}
return true;
}

102
Input/Dennis Input/Main.cpp Normal file
View File

@ -0,0 +1,102 @@
#include "RawInputWrapper.h"
// include the basic windows header file
#include <windows.h>
#include <windowsx.h>
#include <vld.h>
#include <cassert>
HWND hWnd;
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// sort through and find what code to run for the message given
switch(message)
{
// this message is read when the window is closed
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
} break;
case WM_KEYUP:
MessageBox(0, L"WM_KEYUP", L"", 0);
break;
case WM_KEYDOWN:
MessageBox(0, L"WM_KEYDOWN", L"", 0);
break;
//case WM_INPUT:
// MessageBox(0, L"WM_INPUT_MAIN", L"", 0);
//break;
}
// Handle any messages the switch statement didn't
return DefWindowProc (hWnd, message, wParam, lParam);
}
void initWindow(HINSTANCE h, int i)
{
// this struct holds information for the window class
WNDCLASSEX wc;
// clear out the window class for use
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = h;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass1";
// register the window class
RegisterClassEx(&wc);
// create the window and use the result as the handle
hWnd = CreateWindowEx(NULL,
L"WindowClass1", // name of the window class
L"Our First Windowed Program", // title of the window
WS_OVERLAPPEDWINDOW, // window style
300, // x-position of the window
300, // y-position of the window
500, // width of the window
400, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
h, // application handle
NULL); // used with multiple windows, NULL
// display the window on the screen
ShowWindow(hWnd, i);
}
void initRaw()
{
RawInputWrapper::Self()->Input_AddDevice(hWnd);
}
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
initWindow(hInstance, nCmdShow);
initRaw();
// this struct holds Windows event messages
MSG msg;
// wait for the next message in the queue, store the result in 'msg'
while(GetMessage(&msg, NULL, 0, 0))
{
// translate keystroke messages into the right format
TranslateMessage(&msg);
// send the message to the WindowProc function
DispatchMessage(&msg);
RawInputWrapper::Self()->Input_Read();
}
RawInputWrapper::Destroy();
return msg.wParam;
}

View File

@ -0,0 +1,104 @@
#ifndef INCLUDE_GUARD_RAW_INPUT_H
#define INCLUDE_GUARD_RAW_INPUT_H
#include "RawInputWrapper.h"
#include "misc.h"
#include <vector>
/**
* TODO:
* 1. Origo in middle of the screen (-1 to 1)
*/
//dx = +2*(x/w) -1
//dx = -2*(y/h) +1
template<class FNC, class PARAM>
struct SubscribeList
{
FNC fnc;
PARAM param;
SubscribeList* next;
};
struct RawInputDeviceInstance
{
RAWINPUTDEVICE description;
};
enum RawInput_Usage
{
RawInput_Usage_pointer = 1,
RawInput_Usage_mouse = 2,
RawInput_Usage_joystick = 4,
RawInput_Usage_gamepad = 5,
RawInput_Usage_keyboard = 6,
RawInput_Usage_keypad = 7,
RawInput_Usage_multiAxisController = 8,
RawInput_Usage_TabletPCcontrols = 9,
};
class RawInput :public RawInputWrapper
{
private:
SubscribeList<INPUT_CALLBACK, const RawInputData*>* _procInput;
bool _enabled;
bool _mouseEnabled;
bool _KeyboardEnabled;
bool _exclusive;
const wchar_t* _errorMsg;
List<RawInputDeviceInstance> _deviceList;
List<RawInputData> _mouseInput;
List<RawInputData> _keyboardInput;
HHOOK _msgHook;
private:
RawInput ();
~RawInput ();
bool _addDevice (const RAWINPUTDEVICE* k, const int& count);
RAWINPUT*_TranslateRawInput (LPARAM l);
void _proccessRawMouseData (RAWMOUSE&);
void _proccessRawKeyboardData (RAWKEYBOARD&);
static LRESULT CALLBACK WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lParam);
public:
static RawInput* Self ();
static void Destroy ();
const wchar_t* Input_GetError () const;
bool Input_AddDevice (IN const HWND& targetApplication);
bool Input_AddDevice (IN const RAWINPUTDEVICE*, IN const int&);
void Input_Subscribe (IN INPUT_CALLBACK fnc);
void Input_Unsubscribe (IN INPUT_CALLBACK fnc);
void Input_Disable ();
void Input_Enable ();
void Input_Read ();
void Mouse_Show ();
void Mouse_Hide ();
void Mouse_Lock ();
void Mouse_Unlock ();
void Mouse_IsBtnPressed (IN RIK);
int Mouse_WheelDelta ();
POINT Mouse_Position ();
void Mouse_Enable ();
void Mouse_Disable ();
bool Keyboard_KeyUp (IN RIK key);
bool Keyboard_KeyDown (IN RIK key);
void Keyboard_Enable ();
void Keyboard_Disable ();
};
#endif

View File

@ -0,0 +1,215 @@
#ifndef RAW_INPUT_H
#define RAW_INPUT_H
#include <Windows.h>
/*********************************************************************/
/***************************** Keycodes ******************************/
/*********************************************************************/
//! Contains keycodes
enum RIK
{
RIK_Backspace = 0x08,
RIK_Tab = 0x09,
RIK_Enter = 0x0D,
RIK_Shift = 0x10,
RIK_Ctrl = 0x11,
RIK_Alt = 0x12,
RIK_Pause = 0x13,
RIK_CapsLock = 0x14,
RIK_Escape = 0x1B,
RIK_Space = 0x20,
RIK_PgUp = 0x21,
RIK_PgDown = 0x22,
RIK_End = 0x23,
RIK_Home = 0x24,
RIK_Left = 0x25,
RIK_Up = 0x26,
RIK_Right = 0x27,
RIK_Down = 0x28,
RIK_PrintScreen = 0x2C,
RIK_Insert = 0x2D,
RIK_Delete = 0x2E,
RIK_0 = 0x30,
RIK_1 = 0x31,
RIK_2 = 0x32,
RIK_3 = 0x33,
RIK_4 = 0x34,
RIK_5 = 0x35,
RIK_6 = 0x36,
RIK_7 = 0x37,
RIK_8 = 0x38,
RIK_9 = 0x39,
RIK_A = 0x41,
RIK_B = 0x42,
RIK_C = 0x43,
RIK_D = 0x44,
RIK_E = 0x45,
RIK_F = 0x46,
RIK_G = 0x47,
RIK_H = 0x48,
RIK_I = 0x49,
RIK_J = 0x4A,
RIK_K = 0x4B,
RIK_L = 0x4C,
RIK_M = 0x4D,
RIK_N = 0x4E,
RIK_O = 0x4F,
RIK_P = 0x50,
RIK_Q = 0x51,
RIK_R = 0x52,
RIK_S = 0x53,
RIK_T = 0x54,
RIK_U = 0x55,
RIK_V = 0x56,
RIK_W = 0x57,
RIK_X = 0x58,
RIK_Y = 0x59,
RIK_Z = 0x5A,
RIK_LeftWindows = 0x5B,
RIK_RightWindows = 0x5C,
RIK_Numpad0 = 0x60,
RIK_Numpad1 = 0x61,
RIK_Numpad2 = 0x62,
RIK_Numpad3 = 0x63,
RIK_Numpad4 = 0x64,
RIK_Numpad5 = 0x65,
RIK_Numpad6 = 0x66,
RIK_Numpad7 = 0x67,
RIK_Numpad8 = 0x68,
RIK_Numpad9 = 0x69,
RIK_Multiply = 0x6A,
RIK_Plus = 0x6B,
RIK_Subtract = 0x6D,
RIK_Decimal = 0x6E,
RIK_Divide = 0x6F,
RIK_F1 = 0x70,
RIK_F2 = 0x71,
RIK_F3 = 0x72,
RIK_F4 = 0x73,
RIK_F5 = 0x74,
RIK_F6 = 0x75,
RIK_F7 = 0x76,
RIK_F8 = 0x77,
RIK_F9 = 0x78,
RIK_F10 = 0x79,
RIK_F11 = 0x7A,
RIK_F12 = 0x7B,
RIK_F13 = 0x7C,
RIK_F14 = 0x7D,
RIK_F15 = 0x7E,
RIK_F16 = 0x7F,
RIK_F17 = 0x80,
RIK_F18 = 0x81,
RIK_F19 = 0x82,
RIK_F20 = 0x83,
RIK_F21 = 0x84,
RIK_F22 = 0x85,
RIK_F23 = 0x86,
RIK_F24 = 0x87,
RIK_Numlock = 0x90,
RIK_ScrlLock = 0x91,
RIK_LeftShift = 0xA0,
RIK_RightShift = 0xA1,
RIK_LeftCtrl = 0xA2,
RIK_RightCtrl = 0xA3,
COUNT
};
enum RIM
{
RIM_LeftBtn = 0x02,
RIM_MiddleBtn = 0x10,
RIM_RightBtn = 0x04,
RIM_Scroll = 0x0400,
};
/*********************************************************************/
/**************************************************************************/
/***************************** Callback data ******************************/
/**************************************************************************/
enum InputType
{
InputType_Keyboard,
InputType_Mouse,
InputType_HID,
};
struct RawMouseData
{
bool shift;
bool alt;
bool ctrl;
RIM key;
bool pressed;
int MousePos_X;
int MousePos_Y;
int delta;
};
struct RawKeyData
{
bool shift;
bool alt;
bool ctrl;
RIK key;
bool released;
};
struct RawInputData
{
InputType type;
union
{
RawMouseData MOUSE_DATA;
RawKeyData KEYBOARD_DATA;
RAWHID HID_DATA;
} data;
};
typedef void(*INPUT_CALLBACK)(const RawInputData*);
/*********************************************************************/
class RawInputWrapper
{
public:
static RawInputWrapper* Self ();
static void Destroy ();
virtual const wchar_t* Input_GetError () const PURE;
virtual bool Input_AddDevice (IN const HWND& targetApplication) PURE;
virtual bool Input_AddDevice (IN const RAWINPUTDEVICE* d, IN const int& count) PURE;
virtual void Input_Subscribe (IN INPUT_CALLBACK fnc) PURE;
virtual void Input_Unsubscribe (IN INPUT_CALLBACK fnc) PURE;
virtual void Input_Disable () PURE;
virtual void Input_Enable () PURE;
virtual void Input_Read () PURE;
virtual void Mouse_Show () PURE;
virtual void Mouse_Hide () PURE;
virtual void Mouse_Lock () PURE;
virtual void Mouse_Unlock () PURE;
virtual void Mouse_IsBtnPressed (IN RIK key) PURE;
virtual int Mouse_WheelDelta () PURE;
virtual POINT Mouse_Position () PURE;
virtual void Mouse_Enable () PURE;
virtual void Mouse_Disable () PURE;
virtual bool Keyboard_KeyUp (IN RIK key) PURE;
virtual bool Keyboard_KeyDown (IN RIK key) PURE;
virtual void Keyboard_Enable () PURE;
virtual void Keyboard_Disable () PURE;
};
#endif

120
Input/Dennis Input/misc.h Normal file
View File

@ -0,0 +1,120 @@
#ifndef MISC_H
#define MISC_H
#include <assert.h>
template<typename T>
class List
{
private:
class Node
{
public:
T value;
Node *next;
Node(T value){ this->value = value; this->next = NULL; }
~Node() {}
};
Node *first;
int nrOfNodes;
public:
List::List()
{
this->first = NULL;
this->nrOfNodes = 0;
}
List::~List()
{
Node *walker = this->first;
for(int i = 0; i<this->nrOfNodes; i++)
{
walker = walker->next;
delete this->first;
this->first = walker;
}
}
List& List::operator=(const List& origObj)
{
if(this->nrOfNodes > 0)
{
Node *walker = this->first;
for(int i = 0; i<this->nrOfNodes; i++)
{
walker = walker->next;
delete this->first;
this->first = walker;
}
}
this->nrOfNodes = 0;
if(origObj.nrOfNodes > 0)
{
Node *walker = origObj.first;
for(int i = 0; i<origObj.nrOfNodes; i++)
{
insertLast(walker->value);
walker = walker->next;
}
}
return *this;
}
void List::push(T value)
{
Node *e = new Node(value);
e->next = this->first;
this->first = e;
e = NULL;
this->nrOfNodes++;
}
T List::pop()
{
T removed;
memset(&removed, 0, sizeof(T));
if(this->nrOfNodes > 0)
{
Node *temp = first;
this->first = first->next;
memcpy(&removed, &temp->value, sizeof(T));
delete temp;
this->nrOfNodes--;
}
return removed;
}
int List::size() const
{
return this->nrOfNodes;
}
void clear()
{
Node *w = this->first;
Node *p = 0;
while (w)
{
p = w;
w = w->next;
delete p;
}
this->first = 0;
}
};
#endif

284
Input/InputController.cpp Normal file
View File

@ -0,0 +1,284 @@
#include "InputController.h"
using namespace Oyster::Input;
namespace
{
bool keys[256] = {0};
bool prevs[256]= {0};
bool mouse[5] = {0};
bool mPrev[5] = {0};
int XPos,YPos,PrevX,PrevY,DeltaX,DeltaY;
}
void Controller::KeyPressed(const WPARAM &Key)
{
prevs[Key]=false;
keys[Key]=true;
}
void Controller::KeyReleased(const WPARAM &Key)
{
prevs[Key]=true;
keys[Key] = false;
}
bool Controller::isKeyDown(const WPARAM &Key)
{
return keys[Key];
}
bool Controller::isKeyPressed(const WPARAM &Key)
{
if(keys[Key] && !prevs[Key])
{
prevs[Key] = keys[Key];
return true;
}
return false;
}
bool Controller::isKeyReleased(const WPARAM &Key)
{
if(!keys[Key] && prevs[Key])
{
prevs[Key] = keys[Key];
return true;
}
return false;
}
void Controller::MouseBtnPressed(const WPARAM &btn)
{
switch(btn)
{
case MK_LBUTTON:
mouse[0] = true;
mPrev[0] = false;
break;
case MK_RBUTTON:
mouse[1] = true;
mPrev[1] = false;
break;
case MK_MBUTTON:
mouse[2] = true;
mPrev[2] = false;
break;
case MK_XBUTTON1:
mouse[3] = true;
mPrev[3] = false;
break;
case MK_XBUTTON2:
mouse[4] = true;
mPrev[4] = false;
break;
}
}
void Controller::MouseBtnReleased(const WPARAM &btn)
{
switch(btn)
{
case MK_LBUTTON:
mouse[0] = false;
mPrev[0] = true;
break;
case MK_RBUTTON:
mouse[1] = false;
mPrev[1] = true;
break;
case MK_MBUTTON:
mouse[2] = false;
mPrev[2] = true;
break;
case MK_XBUTTON1:
mouse[3] = false;
mPrev[3] = true;
break;
case MK_XBUTTON2:
mouse[4] = false;
mPrev[4] = true;
break;
}
}
bool Controller::isMouseBtnDown(const WPARAM &Btn)
{
switch(Btn)
{
case MK_LBUTTON:
return mouse[0];
case MK_RBUTTON:
return mouse[1];
case MK_MBUTTON:
return mouse[2];
case MK_XBUTTON1:
return mouse[3];
case MK_XBUTTON2:
return mouse[4];
}
return false;
}
bool Controller::isMouseBtnPressed(const WPARAM &Btn)
{
switch(Btn)
{
case MK_LBUTTON:
if(mouse[0] && !mPrev[0])
{
mPrev[0] = mouse[0];
return true;
}
return false;
case MK_RBUTTON:
if(mouse[1] && !mPrev[1])
{
mPrev[1] = mouse[1];
return true;
}
return false;
case MK_MBUTTON:
if(mouse[2] && !mPrev[2])
{
mPrev[2] = mouse[2];
return true;
}
return false;
case MK_XBUTTON1:
if(mouse[3] && !mPrev[3])
{
mPrev[3] = mouse[3];
return true;
}
return false;
case MK_XBUTTON2:
if(mouse[4] && !mPrev[4])
{
mPrev[4] = mouse[4];
return true;
}
return false;
}
return false;
}
bool Controller::isMouseBtnReleased(const WPARAM &Btn)
{
switch(Btn)
{
case MK_LBUTTON:
if(!mouse[0] && mPrev[0])
{
mPrev[0] = mouse[0];
return true;
}
return false;
case MK_RBUTTON:
if(!mouse[1] && mPrev[1])
{
mPrev[1] = mouse[1];
return true;
}
return false;
case MK_MBUTTON:
if(!mouse[2] && mPrev[2])
{
mPrev[2] = mouse[2];
return true;
}
return false;
case MK_XBUTTON1:
if(!mouse[3] && mPrev[3])
{
mPrev[3] = mouse[3];
return true;
}
return false;
case MK_XBUTTON2:
if(!mouse[4] && mPrev[4])
{
mPrev[4] = mouse[4];
return true;
}
return false;
}
return false;
}
void Controller::MouseMove(int x,int y)
{
PrevY = YPos;
PrevX = XPos;
XPos = x;
YPos = y;
DeltaY = YPos - PrevY;
DeltaX = XPos - PrevX;
}
int Controller::GetY()
{
return YPos;
}
int Controller::GetX()
{
return XPos;
}
float Controller::GetAnalogX()
{
float f = (float)XPos;
f /=( Window::Size.left/2);
return f;
}
float Controller::GetAnalogY()
{
float f = (float)YPos;
f /=( Window::Size.top/2);
return f;
}
int Controller::GetDeltaY()
{
return DeltaY;
}
int Controller::GetDeltaX()
{
return DeltaX;
}
void Controller::ResetDeltaX()
{
DeltaX = 0;
}
void Controller::ResetDeltaY()
{
DeltaY = 0;
}
void Controller::RestrictMouse(bool restrict)
{
Oyster::Window::CaptureMouse(restrict);
}
//sets x=0,y=0 to be the center oc the client area
void Controller::OrigoCenter()
{
int x = Window::Size.left/2;
int y = Window::Size.top/2;
Window::SetMouseOffset(-x,-y);
}
//default
void Controller::OrigoTopLeft()
{
Oyster::Window::SetMouseOffset(0,0);
}

63
Input/InputController.h Normal file
View File

@ -0,0 +1,63 @@
#pragma once
#ifndef InputController_H
#define InputController_H
#include "../Window/Window.h"
//READ http://msdn.microsoft.com/en-us/library/windows/desktop/ms648380(v=vs.85).aspx#_win32_Confining_a_Cursor
namespace Oyster
{
class Window;
namespace Input
{
class Controller
{
friend class ::Oyster::Window;
private:
//Keybord events from Oyster::Window
static void KeyPressed(const WPARAM &Key);
//Keybord events from Oyster::Window
static void KeyReleased(const WPARAM &Key);
//Mouse events from Oyster::Window
static void MouseMove(int x,int y);
//Mouse events from Oyster::Window
static void MouseBtnPressed(const WPARAM &Btn);
static void MouseBtnReleased(const WPARAM &Btn);
public:
//Polling Functions
static bool isKeyDown(const WPARAM &Key);
static bool isKeyPressed(const WPARAM &Key);
static bool isKeyReleased(const WPARAM &Key);
static bool isMouseBtnDown(const WPARAM &Btn);
static bool isMouseBtnPressed(const WPARAM &Btn);
static bool isMouseBtnReleased(const WPARAM &Btn);
static int GetX();
static int GetY();
static float GetAnalogX();
static float GetAnalogY();
static int GetDeltaX();
static int GetDeltaY();
//Controll Functions
static void ResetDeltaX();
static void ResetDeltaY();
//off by default
static void RestrictMouse(bool b = true);
//sets x=0,y=0 to be the center oc the client area
static void OrigoCenter();
//default
static void OrigoTopLeft();
};
}
}
#endif

216
Misc/Utilities.cpp Normal file
View File

@ -0,0 +1,216 @@
/////////////////////////////////////////////////////////////////////
// Utility Collection of Miscellanious Handy Functions
// © Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#include "Utilities.h"
#include <sstream>
#include <locale>
using ::std::vector;
using ::std::string;
namespace Utility
{
// PRIVATE STATIC ////////////////////////////////////////////////////
namespace PrivateStatic
{
const ::std::locale systemDefaultLocale = ::std::locale();
}
// STRING ////////////////////////////////////////////////////////////
namespace String
{
vector<string> & split( vector<string> &output, const string &str, char delim, string::size_type offset )
{
if( str.length() > 0 )
{
while( offset < str.length() ) // trim
{
if( str[offset] == delim )
++offset;
else break;
}
string::size_type delimPos = str.find_first_of( delim, offset );
if( delimPos == string::npos )
{
if( str.length() > offset )
output.push_back( str.substr( offset, str.length() - offset ) );
}
else
{
if( delimPos > offset )
output.push_back( str.substr( offset, delimPos - offset ) );
String::split( output, str, delim, delimPos + 1 );
}
}
return output;
}
vector<string> & split( vector<string> &output, const string &str, const string &delim, string::size_type offset )
{
if( str.length() > 0 )
{
string::size_type delimPos = str.find_first_of( delim, offset );
if( delimPos == string::npos )
{
if( str.length() > offset )
output.push_back( str.substr( offset, str.length() - offset ) );
}
else
{
if( delimPos > offset )
output.push_back( str.substr( offset, delimPos - offset ) );
String::split( output, str, delim, delimPos + delim.length() );
}
}
return output;
}
vector<string> & split( vector<string> &output, const string &str, const vector<string> &delim, string::size_type offset )
{
if( str.length() > 0 )
{
string::size_type firstDelimPos = str.length(), delimPos;
vector<string>::size_type numDelims = delim.size(), delimRef = 0;
for( vector<string>::size_type i = 0; i < numDelims ; ++i )
{
delimPos = str.find_first_of( delim[i], offset );
if( delimPos != string::npos ) if( delimPos < firstDelimPos )
{
delimRef = i;
firstDelimPos = delimPos;
}
}
if( firstDelimPos == str.length() )
{
if( str.length() > offset )
output.push_back( str.substr( offset, str.length() - offset ) );
}
else
{
if( firstDelimPos > offset )
output.push_back( str.substr( offset, firstDelimPos - offset ) );
String::split( output, str, delim, firstDelimPos + delim[delimRef].length() );
}
}
return output;
}
string trim( const string &str )
{
string::size_type first = 0,
last = str.length();
if( last == 0 ) return str;
while( first < last )
{
if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
++first;
else break;
}
--last;
while( last > first )
{
if( str[last] == ' ' || str[last] == '\t' || str[last] == '\r' || str[last] == '\n' )
--last;
else break;
}
if( first == last ) if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
return "";
return str.substr( first, (++last) - first );
}
string & toLowerCase( string &output, const string &str )
{
int length = (int)str.length();
output.resize( length );
for( int i = 0; i < length; ++i )
output[i] = ::std::tolower( str[i], ::std::locale() );
return output;
}
string & toLowerCase( string &str )
{
int length = (int)str.length();
for( int i = 0; i < length; ++i )
str[i] = ::std::tolower( str[i], ::std::locale() );
return str;
}
string & toUpperCase( string &output, const string &str )
{
int length = (int)str.length();
output.resize( length );
for( int i = 0; i < length; ++i )
output[i] = ::std::toupper( str[i], ::std::locale() );
return output;
}
string & toUpperCase( string &str )
{
int length = (int)str.length();
for( int i = 0; i < length; ++i )
str[i] = ::std::toupper( str[i], ::std::locale() );
return str;
}
string & extractDirPath( string &output, const string &file, char dirDelimeter )
{
string d = " ";
d[0] = dirDelimeter;
return String::extractDirPath( output, file, d );
}
string & extractDirPath( string &output, const string &file, const string &dirDelimeter )
{
string::size_type end = file.find_last_of( dirDelimeter );
if( end == string::npos )
output = "";
else
{
++end;
output.resize( end );
for( string::size_type i = 0; i < end; ++i )
output[i] = file[i];
}
return output;
}
string & replaceCharacters( string &str, char characterToReplace, char newCharacter, const string::size_type &offset, const string::size_type &end )
{
string::size_type i = offset;
while( true )
{
i = str.find_first_of( characterToReplace, i );
if( i >= end ) break;
str[i++] = newCharacter;
}
return str;
}
}
// STREAM ////////////////////////////////////////////////////////////
namespace Stream
{
float* readFloats( float *output, ::std::istream &input, unsigned int numFloats )
{
string str;
for( unsigned int i = 0; i < numFloats; ++i )
{
input >> str;
output[i] = (float)::std::atof( str.c_str() );
}
return output;
}
}
}

80
Misc/Utilities.h Normal file
View File

@ -0,0 +1,80 @@
/////////////////////////////////////////////////////////////////////
// Utility Collection of Miscellanious Handy Functions
// © Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef UTILITIES_H
#define UTILITIES_H
#include <string>
#include <istream>
#include <vector>
#include <locale>
namespace Utility
{
namespace String
{
// note to self: add a whitespaceSplit method?
::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, char delim, ::std::string::size_type offset = 0 );
::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::string &delim, ::std::string::size_type offset = 0 );
::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::vector<::std::string> &delim, ::std::string::size_type offset = 0 );
::std::string trim( const ::std::string &str );
::std::string & toLowerCase( ::std::string &output, const ::std::string &str );
::std::string & toLowerCase( ::std::string &str );
::std::string & toUpperCase( ::std::string &output, const ::std::string &str );
::std::string & toUpperCase( ::std::string &str );
::std::string & extractDirPath( ::std::string &output, const ::std::string &file, char dirDelimeter );
::std::string & extractDirPath( ::std::string &output, const ::std::string &file, const ::std::string &dirDelimeter );
::std::string & replaceCharacters( ::std::string &str, char characterToReplace, char newCharacter, const ::std::string::size_type &offset = 0, const ::std::string::size_type &end = ::std::string::npos );
}
namespace Stream
{
float* readFloats( float *output, ::std::istream &input, unsigned int numFloats );
}
namespace StaticArray
{
template<typename ElementType, unsigned int num>
inline unsigned int numElementsOf( const ElementType(&)[num] )
{ return num; }
}
namespace Element
{
template<typename ElementType>
inline void swap( ElementType &elementA, ElementType &elementB, ElementType &swapSpace )
{ swapSpace = elementA; elementA = elementB; elementB = swapSpace; }
template<typename ElementType>
inline void swap( ElementType &elementA, ElementType &elementB )
{ ElementType swapSpace; swap( elementA, elementB, swapSpace ); }
}
namespace Value
{
template<typename ValueType>
inline ValueType abs( const ValueType &value )
{ return value < 0 ? value * -1 : value; }
template<typename ValueType>
inline ValueType max( const ValueType &valueA, const ValueType &valueB )
{ return valueA > valueB ? valueA : valueB; }
template<typename ValueType>
inline ValueType min( const ValueType &valueA, const ValueType &valueB )
{ return valueA < valueB ? valueA : valueB; }
template<typename ValueType>
inline ValueType radian( const ValueType &degree )
{ return degree * (3.1415926535897932384626433832795f / 180.0f); }
template<typename ValueType>
inline ValueType degree( const ValueType &radian )
{ return radian * (180.0f / 3.1415926535897932384626433832795f); }
}
}
#endif

75
Misc/WinTimer.cpp Normal file
View File

@ -0,0 +1,75 @@
#include "WinTimer.h"
using namespace ::Utility;
namespace PrivateStatic
{
LARGE_INTEGER ticksPerSecond = { 0 };
double secondsPerTick = 0.0f;
class WatchDog
{
public:
WatchDog( )
{
if( QueryPerformanceFrequency( &ticksPerSecond ) > 0 )
secondsPerTick = ((double)1.0f) / (double) ticksPerSecond.QuadPart;
}
} watchDog;
}
WinTimer::WinTimer( ) : isPaused(false)
{ this->reset(); }
void WinTimer::reset( )
{
this->isPaused = false;
this->pauseCount.QuadPart = 0;
QueryPerformanceCounter( &this->startTick );
}
void WinTimer::pause( )
{
if( !this->isPaused )
{
this->isPaused = true;
QueryPerformanceCounter( &this->pauseStart );
}
}
void WinTimer::resume( )
{
if( this->isPaused )
{
this->isPaused = false;
LARGE_INTEGER currentTick;
QueryPerformanceCounter( &currentTick );
this->pauseCount.QuadPart += currentTick.QuadPart - this->pauseStart.QuadPart;
}
}
double WinTimer::getElapsedSeconds( ) const
{
if( this->isPaused )
{
LARGE_INTEGER totalTick = this->pauseStart;
totalTick.QuadPart -= this->startTick.QuadPart;
totalTick.QuadPart -= this->pauseCount.QuadPart;
return PrivateStatic::secondsPerTick * (double)totalTick.QuadPart;
}
else
{
LARGE_INTEGER currentTick;
QueryPerformanceCounter( &currentTick );
currentTick.QuadPart -= this->startTick.QuadPart;
currentTick.QuadPart -= this->pauseCount.QuadPart;
return PrivateStatic::secondsPerTick * (double)currentTick.QuadPart;
}
}
LARGE_INTEGER WinTimer::getCurrentTick( ) const
{
LARGE_INTEGER currentTick;
QueryPerformanceCounter( &currentTick );
return currentTick;
}

32
Misc/WinTimer.h Normal file
View File

@ -0,0 +1,32 @@
/////////////////////////////////////////////////////////////////////
// Instanciable Timer class for windows
// © Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef WINTIMER_H
#define WINTIMER_H
#include <Windows.h>
namespace Utility
{
class WinTimer
{
public:
WinTimer( );
void reset( );
void pause( );
void resume( );
double getElapsedSeconds( ) const;
LARGE_INTEGER getCurrentTick( ) const;
private:
LARGE_INTEGER startTick, pauseStart, pauseCount;
bool isPaused;
};
}
#endif

View File

@ -0,0 +1,262 @@
#include "Event.h"
using namespace Event;
//----------------------------
// BulletCreated class definitions
BulletCreated::BulletCreated(int ownerID, Float3 position, Float3 direction)
:
GameEvent()
{
data.owner=ownerID;
data.head=direction;
}
void BulletCreated::LoadRawData(char* d)
{
memcpy(&data, d, GetSize());
/*int offset=0;
memcpy(&data.position, data, sizeof(Float3));
offset+=sizeof(Float3);
memcpy(&data.head, d+offset, sizeof(Float3));
offset+=sizeof(Float3);
memcpy(&data.owner, d+offset, sizeof(int));*/
}
void BulletCreated::SaveRawData(char* d)
{
memcpy(d, &data, GetSize());
}
//----------------------------
// BulletHit class definitions
BulletHit::BulletHit(int attacker, int hitPlayer)
:
GameEvent()
{
data.hitTarget=hitPlayer;
data.attackingTarget=attacker;
//this->hpLeft=hl;
//this->shieldLeft=sl;
}
void BulletHit::LoadRawData(char* d)
{
memcpy(&data, d, GetSize());
}
void BulletHit::SaveRawData(char* d)
{
memcpy(d, &data, GetSize());
}
ScoreUpdate::ScoreUpdate(Score* scores)
{
for (int i=0; i<PLAYER_MAX_COUNT; i++)
{
data.scoreboard[i]=scores[i];
}
}
void ScoreUpdate::LoadRawData(char* d)
{
memcpy(&data, d, GetSize());
}
void ScoreUpdate::SaveRawData(char* d)
{
memcpy(d, &data, GetSize());
}
//----------------------------
// ShipSpawned class definitions
ShipSpawned::ShipSpawned(Float3 position, int id)
:
GameEvent()
{
data.position=position;
data.playerID=id;
}
void ShipSpawned::LoadRawData(char* d)
{
memcpy(&data, d, this->GetSize());
/*int offset=0;
memcpy(&data.position, data, sizeof(Float3));
offset+=sizeof(Float3);
memcpy(&playerID, data+offset, sizeof(int));*/
}
void ShipSpawned::SaveRawData(char* d)
{
memcpy(d, &data, GetSize());
}
//----------------------------
// GameEnded class definitions
GameEnded::GameEnded()
:
GameEvent()
{
}
GameEnded::GameEnded(int winner)
:
GameEvent()
{
data.winningTeam=winner;
}
void GameEnded::LoadRawData(char* d)
{
memcpy(&data, d, GetSize());
/*int offset=0;
memcpy(&eventPosition, data, sizeof(Float3));
offset+=sizeof(Float3);
memcpy(&winningTeam, data+offset, sizeof(int));
offset+=sizeof(int);
for (int i=0; i<PLAYER_MAX_COUNT; i++)
{
memcpy(&data.scoreboard[i], data+offset, sizeof(Score));
offset+=sizeof(Score);
}*/
}
void GameEnded::SaveRawData(char* d)
{
memcpy(d, &data, GetSize());
}
void GameEnded::setScore(int i, Score score)
{
data.scoreboard[i]=score;
}
void GameEnded::setScore(int i, int k, int d, int tk)
{
data.scoreboard[i].id=i;
data.scoreboard[i].kills=k;
data.scoreboard[i].deaths=d;
data.scoreboard[i].teamkills=tk;
}
void GameEnded::sortScore()
{
float sort[PLAYER_MAX_COUNT];
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
sort[i]=((float)(data.scoreboard[i].kills-data.scoreboard[i].teamkills))/(float)data.scoreboard[i].deaths;
}
Score tmp;
int bestID=0;
float bestScore;
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
bestScore=sort[i];
bestID=i;
for (int j=i; j<PLAYER_MAX_COUNT; j++)
{
if(bestScore<sort[j])
{
bestID=j;
bestScore=sort[j];
}
}
tmp=data.scoreboard[i];
data.scoreboard[i]=data.scoreboard[bestID];
data.scoreboard[bestID]=tmp;
}
}
//----------------------------
// ShipDestroyed class definitions
ShipDestroyed::ShipDestroyed(int pid, int kid)
:
GameEvent()
{
data.playerID=pid;
data.killerID=kid;
}
void ShipDestroyed::setScore(int i, Score score)
{
data.scoreboard[i]=score;
}
void ShipDestroyed::setScore(int i, int k, int d, int tk)
{
data.scoreboard[i].id=i;
data.scoreboard[i].kills=k;
data.scoreboard[i].deaths=d;
data.scoreboard[i].teamkills=tk;
}
void ShipDestroyed::sortScore()
{
float sort[PLAYER_MAX_COUNT];
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
sort[i]=((float)(data.scoreboard[i].kills-data.scoreboard[i].teamkills))/data.scoreboard[i].deaths;
}
Score tmp;
int bestID=0;
float bestScore;
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
bestScore=sort[i];
bestID=i;
for (int j=i; j<PLAYER_MAX_COUNT; j++)
{
if(bestScore<sort[j])
{
bestID=j;
bestScore=sort[j];
}
}
tmp=data.scoreboard[i];
data.scoreboard[i]=data.scoreboard[bestID];
data.scoreboard[bestID]=tmp;
}
}
void ShipDestroyed::LoadRawData(char* d)
{
memcpy(&data, d, GetSize());
/*int offset=0;
memcpy(&eventPosition, data, sizeof(Float3));
offset+=sizeof(Float3);
memcpy(&playerID, data+offset, sizeof(int));
offset+=sizeof(int);
memcpy(&killerID, data+offset, sizeof(int));
offset+=sizeof(int);
for (int i=0; i<PLAYER_MAX_COUNT; i++)
{
memcpy(&data.scoreboard[i], data+offset, sizeof(Score));
offset+=sizeof(Score);
}*/
}
void ShipDestroyed::SaveRawData(char* d)
{
memcpy(d, &data, GetSize());
}
Event::Type Event::getEventType(Event::GameEvent* evt)
{
if (typeid(*evt)==typeid(Event::BulletCreated))
{
return eBulletCreated;
}
else if(typeid(*evt)==typeid(Event::BulletHit))
{
return eBulletHit;
}
else if(typeid(*evt)==typeid(Event::ShipSpawned))
{
return eShipSpawned;
}
else if(typeid(*evt)==typeid(Event::GameEnded))
{
return eGameEnded;
}
else if(typeid(*evt)==typeid(Event::ShipDestroyed))
{
return eShipDestroyed;
}
else if(typeid(*evt)==typeid(Event::ScoreUpdate))
{
return eScoreUpdate;
}
printf("UNSUPPORTED EVENT at getEventType, Event.cpp\n");
return UNSUPPORTED_TYPE;
}

View File

@ -0,0 +1,142 @@
#include "NetworkIncludes.h"
#include "EventStructs.h"
#pragma once
#ifndef EVENT_H
#define EVENT_H
//There's a variable called eventList in Session.
//if you push_back any type of event, the server will pick them up in order after every update() is run.
//Try to keep events pointer-free. Trying to send a class with a pointer over a socket will result in a problem because
//it will send the pointer rather than the data in the pointer. That results in either
//A: Program crashing because it's not allowed to read that space if it's on the same computer as the server or
//B: Program crashing because the pointer most probably points to an unused space if the client is on a separate computer.
//This is the basic event class.
//a position should always be given with all events, to use as a main location for sounds, effects, or whatever. We can remove it if we decide it's not needed later on.
namespace Event
{
class GameEvent
{
protected:
public:
GameEvent(){}
virtual int GetSize()=0;
virtual void LoadRawData(char* d)=0;
virtual void SaveRawData(char* d)=0;
};
//When a player fires a projectile, a BulletCreated event should be added.
class BulletCreated : public GameEvent
{
private:
EventStruct::BulletCreatedStruct data;
public:
BulletCreated():GameEvent(){}
BulletCreated(int ownerID, Float3 position, Float3 Head);
int GetOwner(){return data.owner;}
int GetSize(){return sizeof(data);}
EventStruct::BulletCreatedStruct GetAsStruct(){return data;}
void LoadRawData(char* d);
void SaveRawData(char* d);
};
class ScoreUpdate : public GameEvent
{
private:
EventStruct::ScoreUpdateStruct data;
public:
ScoreUpdate():GameEvent(){}
ScoreUpdate(Score* scoreboard);
int GetSize(){return sizeof(data);}
EventStruct::ScoreUpdateStruct GetAsStruct(){return data;}
void LoadRawData(char* d);
void SaveRawData(char* d);
};
//When some kind of player-fired projectile hits an enemy, a BulletHit even should be added.
class BulletHit : public GameEvent
{
private:
EventStruct::BulletHitStruct data;
public:
BulletHit():GameEvent(){}
BulletHit(int attacker, int hitPlayer);
int getAttackerID(){return data.attackingTarget;}
int getHitTargetID(){return data.hitTarget;}
int GetSize(){return sizeof(data);}
EventStruct::BulletHitStruct GetAsStruct(){return data;}
void LoadRawData(char* d);
void SaveRawData(char* d);
};
//Shipspawned event, for when a ship respawns.
//In ShipSpawned, all data that the client requires should be given.
class ShipSpawned : public GameEvent
{
private:
EventStruct::ShipSpawnedStruct data;
public:
ShipSpawned():GameEvent(){}
ShipSpawned(Float3 position, int id);
int GetSize(){return sizeof(data);}
EventStruct::ShipSpawnedStruct GetAsStruct(){return data;}
void LoadRawData(char* d);
void SaveRawData(char* d);
};
class ShipDestroyed : public GameEvent
{
public:
EventStruct::ShipDestroyedStruct data;
public:
ShipDestroyed():GameEvent(){}
ShipDestroyed(int pid, int kid);
void setScore(int i, Score score);
void setScore(int i, int k, int d, int tk);
void sortScore();
int getDestroyedID() const {return data.playerID;}
int getAttackerID() const {return data.killerID;}
EventStruct::ShipDestroyedStruct GetAsStruct(){return data;}
int GetSize(){return sizeof(data);}
void LoadRawData(char* d);
void SaveRawData(char* d);
};
class GameEnded : public GameEvent
{
private:
EventStruct::GameEndedStruct data;
//Have some variables which shows scores of player, who won, etc
//you just need the ids. Don't send names etc.
public:
GameEnded();
GameEnded(int winner);
void setScore(int i, Score score);
void setScore(int i, int k, int d, int tk);
void sortScore();
int GetSize(){return sizeof(data);}
EventStruct::GameEndedStruct GetAsStruct(){return data;}
void LoadRawData(char* d);
void SaveRawData(char* d);
};
enum Type
{
UNSUPPORTED_TYPE,
eBulletCreated,
eBulletHit,
eShipSpawned,
eGameEnded,
eShipDestroyed,
eScoreUpdate
};
Event::Type getEventType(Event::GameEvent* evt);
}
#endif

View File

@ -0,0 +1,55 @@
#include "NetworkIncludes.h"
#include "NetworkConstants.h"
#ifndef NET_EVT_STRUCTS_H
#define NET_EVT_STRUCTS_H
struct Score
{
int id;//Leaderboard var
int kills;
int deaths;
int teamkills;
Score(){id=0;kills=0;deaths=0;teamkills=0;}
Score& operator+=(const Score add)
{
id+=add.id;
kills+=add.kills;
deaths+=add.deaths;
teamkills+=add.teamkills;
return *this;
}
};
namespace EventStruct
{
struct BulletCreatedStruct
{
Float3 position;
Float3 head;
int owner;
};
struct BulletHitStruct
{
int hitTarget;
int attackingTarget;
};
struct ShipSpawnedStruct
{
Float3 position;
int playerID;
};
struct ShipDestroyedStruct
{
int playerID;
int killerID;
Score scoreboard[PLAYER_MAX_COUNT];
};
struct ScoreUpdateStruct
{
Score scoreboard[PLAYER_MAX_COUNT];
};
struct GameEndedStruct
{
int winningTeam;
Score scoreboard[PLAYER_MAX_COUNT];
};
}
#endif

View File

@ -0,0 +1,11 @@
#ifndef NETWORK_H
#define NETWORK_H
#include "NetworkIncludes.h"
#include "EventStructs.h"
#include "NetworkUpdateStructs.h"
#include "NetworkInitStructs.h"
#include "EventStructs.h"
#include "Event.h"
#include "NetworkMiscFunctions.h"
#include "NetworkTimer.h"
#endif

View File

@ -0,0 +1,11 @@
#pragma once
#ifndef NET_CONST_H
#define NET_CONST_H
//const int PLAYER_WAIT_COUNT = 1;
const int PLAYER_MAX_COUNT = 8;
const float LOBBY_WAIT_TIME = 4;
/*namespace Network
{
void LoadData(){}
}*/
#endif

View File

@ -0,0 +1,23 @@
#ifndef NET_INCL_H
#define NET_INCL_H
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <string>
#include <ctime>
#include <iostream>
#include "OysterMath.h"
using namespace Oyster::Math;
//ws2_32.lib is a lib file the linker requires for winsock compilation
#pragma comment(lib, "Ws2_32.lib")
#endif

View File

@ -0,0 +1,70 @@
#ifndef NET_INIT_STRUCTS_H
#define NET_INIT_STRUCTS_H
#include "NetworkIncludes.h"
#include "NetworkConstants.h"
struct PlayerInitStruct
{
INT8 pid;
int teamid;
Oyster::Math::Float4x4 position;
PlayerInitStruct()
{
pid=0;
//position=Oyster::Math::Float4x4::identity;
}
};
struct GameInitData
{
INT8 pid;
//std::string playerNames[PLAYER_MAX_COUNT];
PlayerInitStruct player[PLAYER_MAX_COUNT];
};
struct LobbyUserStruct
{
INT8 pid;
INT8 shipID;
char usrName[15];
LobbyUserStruct()
{
pid=0;
shipID=0;
usrName[0]='\0';
}
void setName(const char* n)
{
strcpy_s(usrName, n);
}
int size()
{
int sz=sizeof(pid);
sz+=sizeof(shipID);
int tmp=(int)strlen(usrName);
sz+=(int)strlen(usrName);
return sz;
}
};
struct LobbyInitData
{
INT8 pid;
INT8 playerCount;
int timer;
LobbyUserStruct players[PLAYER_MAX_COUNT];
LobbyInitData()
{
pid=0;
for (int i=0; i<PLAYER_MAX_COUNT; i++)
{
players[i].pid=i;
}
}
int size()
{
int sz=sizeof(pid);
for (int i=0; i<PLAYER_MAX_COUNT; i++)
sz+=players[i].size();
return sz;
}
};
#endif

View File

@ -0,0 +1,12 @@
#include "NetworkMiscFunctions.h"
std::vector<std::string> splitString(const char* p_inStr, char p_delim)
{
std::stringstream ss(p_inStr);
std::vector<std::string> elems;
std::string item;
while(std::getline(ss, item, p_delim))
{
elems.push_back(item);
}
return elems;
}

View File

@ -0,0 +1,9 @@
#ifndef NET_MISC_FNC_H
#define NET_MISC_FNC_H
#include <string>
#include <vector>
#include <sstream>
std::vector<std::string> splitString(const char* p_inStr, char p_delim);
#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
#endif

View File

@ -0,0 +1,85 @@
#include "NetworkTimer.h"
NetworkTimer::NetworkTimer()
:
c_SecondsPerCount(0.0),
c_DeltaTime(-1.0),
c_BaseTime(0),
c_PausedTime(0),
c_PrevTime(0),
c_CurrTime(0),
c_Stopped(false)
{
__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
c_SecondsPerCount =1.0 / (double)countsPerSec;
QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
}
void NetworkTimer::start()
{
__int64 p_StartTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
if(c_Stopped)
{
c_PausedTime += (p_StartTime-c_StopTime);
c_PrevTime = p_StartTime;
c_StopTime = 0;
c_Stopped = false;
}
}
__int64 NetworkTimer::getTime()
{
__int64 testInt;
return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
return testInt;
}
void NetworkTimer::stop()
{
if(!c_Stopped)
{
__int64 p_CurrTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
c_StopTime = p_CurrTime;
c_Stopped = true;
}
}
void NetworkTimer::reset()
{
__int64 p_CurrTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
c_BaseTime = p_CurrTime;
c_PrevTime = p_CurrTime;
c_StopTime = 0;
c_Stopped = false;
}
void NetworkTimer::tick()
{
if (c_Stopped)
{
c_DeltaTime= 0.0;
return;
}
__int64 p_CurrTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
c_CurrTime=p_CurrTime;
c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
c_PrevTime=c_CurrTime;
if(c_DeltaTime<0.0) c_DeltaTime=0.0;
}
float NetworkTimer::getGameTime() const
{
if(c_Stopped)
{
return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
} else
{
return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
}
}
float NetworkTimer::getDeltaTime() const
{
return (float)c_DeltaTime;
}

View File

@ -0,0 +1,25 @@
#include "NetworkIncludes.h"
#ifndef _NET_TIMER_H
#define _NET_TIMER_H
class NetworkTimer
{
private:
double c_SecondsPerCount;
double c_DeltaTime;
__int64 c_BaseTime;
__int64 c_PausedTime;
__int64 c_StopTime;
__int64 c_PrevTime;
__int64 c_CurrTime;
bool c_Stopped;
public:
NetworkTimer();
__int64 getTime();
void start();
void stop();
void reset();
void tick();
float getGameTime() const;
float getDeltaTime() const;
};
#endif

View File

@ -0,0 +1,62 @@
#ifndef NET_UPD_STRUCTS_H
#define NET_UPD_STRUCTS_H
#include "NetworkIncludes.h"
namespace Network
{
struct EffectData
{
int identifier;
Float3 head;
Float3 tail;
};
struct ServerToClientUpdateData
{
int pid;
Oyster::Math::Float4x4 position;
float dirVecLen;
int hp;
int shield;
long updateCount;
ServerToClientUpdateData()
{
pid=0;
updateCount=0;
hp=0;
shield=0;
}
};
const int SERVER_PLAYER_DATA_SIZE = 84;
struct ClientToServerUpdateData
{
__int8 pid;
//Oyster::Math::Float4x4 position;
__int8 forward;
__int8 roll;
__int8 straferight;
__int8 strafeup;
bool firePrim;
bool fireSecond;
bool fireSpecial;
long updateCount;
bool braking;
float TurnHor;
float TurnVer;
ClientToServerUpdateData()
{
pid=0;
forward=0;
roll=0;
straferight=0;
strafeup=0;
firePrim=false;
fireSecond=false;
fireSpecial=false;
updateCount=0;
braking=false;
TurnHor= 0.0f;
TurnVer= 0.0f;
}
};
const int CLIENT_PLAYER_DATA_SIZE = sizeof(ClientToServerUpdateData);
}
#endif

View File

@ -0,0 +1 @@
#include "NetworkUpdateStructs.h"

View File

@ -0,0 +1,112 @@
#include "SocketClient.h"
#pragma once
#ifndef SOCKET_DATA_CPP
#define SOCKET_DATA_CPP
/*std::vector<std::string> splitString(char* p_inStr, char p_delim)
{
std::stringstream ss(p_inStr);
std::vector<std::string> elems;
std::string item;
while(std::getline(ss, item, p_delim))
{
elems.push_back(item);
}
return elems;
}*/
void SocketClient::parseReceivedData(/*char* data, int size*/)
{
switch (recvBuffer[0]) // TODO: runtime error occured here when shutting down client. recvBuffer invalid pointer. ~Dan 2013-05-14
{
case 1://It's data
parseData();
break;
case 2://For the moment, this is only for init data
parseGameInitData();
break;
case 3://It's a chat message
parseMessage();
break;
case 4://It's a server message
parseServermessage();
break;
case 5://Player has been connected to a game lobby
parseLobbyInitData();
break;
case 6://It's an event
parseReceivedEvent();
break;
case 7:
parseReceivedEffect();
break;
case 8:
parseRenderData();
break;
default:
int a=0;
}
}
void SocketClient::parseRenderData()
{
receiveRenderData(recvBuffer+1, recvBufLen-1);
}
void SocketClient::parseReceivedEffect()
{
receiveEffectData(recvBuffer+1, recvBufLen-1);
}
void SocketClient::parseReceivedEvent()
{
receiveEvent(recvBuffer+1);
}
void SocketClient::parseGameInitData()
{
receiveGameInitData(recvBuffer+1);
connectStatus=true;
}
void SocketClient::parseLobbyInitData()
{
receiveLobbyInitData(recvBuffer+1, recvBufLen-1);
connectStatus=true;
}
void SocketClient::parseServermessage()
{
recvBuffer[recvBufLen]='\0';
if(!strcmp(recvBuffer+1, "connected"))
{
connectStatus=true;
connStatus=ONLINE_MAINMENU;
receiveConnStatus(ONLINE_MAINMENU);
}
else if(!strcmp(recvBuffer+1, "qst"))
{
connStatus=ONLINE_QUEUEING;
receiveConnStatus(ONLINE_QUEUEING);
}
else if(!strcmp(recvBuffer+1, "qed"))
{
connStatus=ONLINE_MAINMENU;
receiveConnStatus(ONLINE_MAINMENU);
}
//Server message of some sort
}
void SocketClient::parseData()
{
//memcpy(&tmpPlayer,buffer+1,playerDataSize);
//playerContPtr->setPlayerStruct(tmpPlayer);
receivePlayerUpdate(recvBuffer+1, recvBufLen-1);
}
void SocketClient::parseMessage()
{
//std::string message;
//message="[Chat] "+users[pid].getUsername()+": "+(buffer+1);
printf("%s\n",recvBuffer+1);
}
#endif

View File

@ -0,0 +1,79 @@
#include "SocketClient.h"
#pragma once
#ifndef SOCKET_INIT_CPP
#define SOCKET_INIT_CPP
bool SocketClient::startReceiveThread()
{
threadhandle[0]=CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)&receiveDataThreadV,
(LPVOID) this,
0,
NULL);
return true;
}
bool SocketClient::startSendDataThread()
{
threadhandle[1]=CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)&receiveDataThreadV,
(LPVOID) this,
0,
NULL);
return true;
}
bool SocketClient::init(int listenPort)
{
return initUDPSocket(listenPort);
}
bool SocketClient::connectToIP(const char* ip, int listenPort, char* initData, int initDataSize)
{
init(listenPort);
//---------------------------------------------
// Set up the port and IP of the server
//Port starts up as a different one from when connected, it changes once the server has exchanged some info with the client
UDPsendAddr.sin_family = AF_INET;
UDPsendAddr.sin_port = htons(UDPSendPort);
UDPsendAddr.sin_addr.s_addr = inet_addr(ip);
TCPsendAddr.sin_family = AF_INET;
TCPsendAddr.sin_port = htons(TCPSendPort);
TCPsendAddr.sin_addr.s_addr = inet_addr(ip);
/*iResult=connect(connTCP, (SOCKADDR *) &TCPsendAddr, addrSize);
if (iResult == SOCKET_ERROR) {
int test=WSAGetLastError();
wprintf(L"connect failed with error: %d\n", WSAGetLastError());
//closesocket(connTCP);
//WSACleanup();
return false;
}/*
iResult=send(connTCP, initData, initDataSize, 0);
if (iResult == SOCKET_ERROR) {
int test=WSAGetLastError();
wprintf(L"connect failed with error: %d\n", WSAGetLastError());
//closesocket(connTCP);
//WSACleanup();
return false;
}*/
iResult = sendto(connUDP,
initData, initDataSize, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"Client UDP sendto failed with error: %d\n", WSAGetLastError());
//closesocket(connUDP);
//WSACleanup();
return false;
}
//connectStatus=true;
connectStatus=false;
return true;
}
#endif

View File

@ -0,0 +1,79 @@
#include "SocketClient.h"
const int maxThreadCount=2;
bool validateIpAddress(const std::string ipAddress)
{
struct sockaddr_in sa;
int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
return result != 0;
}
/*int main(int argc, char *argv[])
{
std::string tst;
bool test=true;
//Multithreading variables
//int nThreads = 0;
//DWORD dwThreadId[maxThreadCount];
//HANDLE threadhandle;
GameClass game;
SocketClient<GameClass> client;
//Sets up the link to the GameClass class.
client.setPlayerContPtr(&game);
//This is the loop which makes the user enter the server address.
while (!client.isReady());
do
{
if (!test)
{
printf("Could not connect to server. Try another IP.\n");
}
else
{
printf("Enter the server ip. \n");
}
getline(std::cin, tst);
if (tst.length()==0)
{
tst="127.0.0.1";
}
if (validateIpAddress(tst))
{
//Tmp init connection message: set username
char* tmp=new char[30];
printf("What is your desired username?\n");
std::cin.getline(tmp,30);
if (strlen(tmp)==0)
{
tmp="Anonymous";
}
printf("Username set to %s\n", tmp);
test=client.connectToIP(tst.c_str(), tmp, strlen(tmp));
}
else
{
printf("Invalid IPaddress. Please enter a new IPaddress.\n");
test=false;
}
} while (!test);
while (!client.isConnected());
Sleep(1000);
//Starts the receive loop
//threadhandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&client.receiveDataThreadV,(LPVOID) &client,0,&dwThreadId[0]);
client.startReceiveThread();
//GetExitCodeThread(threadhandle, eCode);
//This is just a loop to receive user input which creates a natural delay for sendUserData.
printf("Write what you want to send\n");
tst="tmp init message";
while (tst.length()>0)
{
client.sendMessage(tst);
client.sendUserData();
getline(std::cin, tst);
}
//Kills off the thread and connection
//DWORD eCode=0;
//TerminateThread(threadhandle, eCode);
client.closeConnection();
return 0;
}*/

View File

@ -0,0 +1,39 @@
#include "SocketClient.h"
bool SocketClient::initTCPSocket(int listenPort)
{
TCPrecvAddr.sin_family = AF_INET;
TCPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
TCPrecvAddr.sin_port = htons(/*TCPRecvPort*/listenPort);
connTCP = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (connTCP == INVALID_SOCKET)
{
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return false;
}
iResult = bind(connTCP, (SOCKADDR *) & TCPrecvAddr, addrSize);
if (iResult == SOCKET_ERROR)
{
int tst=WSAGetLastError();
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
iResult = closesocket(connTCP);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
//WSACleanup();
return false;
}
return true;
}
bool SocketClient::sendDataTCP(const char* data, int size)
{
iResult = sendto(connTCP,
data, size, 0, (SOCKADDR *) & TCPsendAddr, addrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"TCP sendto failed with error: %d\n", WSAGetLastError());
return false;
}
return true;
}

View File

@ -0,0 +1,39 @@
#include "SocketClient.h"
bool SocketClient::initUDPSocket(int listenPort)
{
UDPrecvAddr.sin_family = AF_INET;
UDPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
UDPrecvAddr.sin_port = htons(listenPort);
//---------------------------------------------
// Create a socket for sending data
connUDP = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (connUDP == INVALID_SOCKET)
{
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return false;
}
iResult = bind(connUDP, (SOCKADDR *) & UDPrecvAddr, addrSize);
if (iResult == SOCKET_ERROR)
{
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
iResult = closesocket(connUDP);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
WSACleanup();
return false;
}
return true;
}
bool SocketClient::sendDataUDP(const char* data, int size)
{
iResult = sendto(connUDP,
data, size, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
//closesocket(connUDP);
//WSACleanup();
return false;
}
return true;
}

View File

@ -0,0 +1,133 @@
#include "SocketClient.h"
#pragma once
#ifndef SOCKET_CLIENT_CPP
#define SOCKET_CLIENT_CPP
SocketClient::SocketClient()
{
playerDataSize=Network::CLIENT_PLAYER_DATA_SIZE;
sendDelayMS=10;
connUDP = INVALID_SOCKET;
connTCP = INVALID_SOCKET;
//sendBuffer=new char[BUFFER_MAX_SIZE];
//sendBufLen=BUFFER_MAX_SIZE;
//ZeroMemory(sendBuffer,sendBufLen);
recvBuffer=new char[BUFFER_MAX_SIZE];
recvBufLen=BUFFER_MAX_SIZE;
ZeroMemory(recvBuffer,recvBufLen);
dataBuf=new char[playerDataSize+1];
dataBuf[0]=1;
//ZeroMemory(b,sizeof(buffer));
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup failed with error: %d\n", iResult);
}
addrSize=sizeof(sockaddr_in);
connectStatus=false;
}
bool SocketClient::sendUserData()
{
//memcpy(dataBuf+1,&playerContPtr->getPlayerData(),playerDataSize);
//return sendData(dataBuf, playerDataSize+1);
printf("NOT YET IMPLEMENTED");
return false;
}
bool SocketClient::sendUserData(char* data, int size)
{
memcpy(dataBuf+1,data,size);
return sendDataUDP(dataBuf, size+1);
}
bool SocketClient::sendMessage(std::string msg)
{
if (msg[0]=='/')
{
//Server command
msg[0]=2;
}
else
{
//Chat message
msg='1'+msg;
msg[0]=3;
}
return sendDataUDP(msg.c_str(), (int)msg.size());
}
bool SocketClient::closeConnection()
{
connectStatus=false;
Sleep(5);
//Give the threads 5 ms to quit themselves before terminating them
DWORD eCode=0;
TerminateThread(threadhandle[0], eCode);
TerminateThread(threadhandle[1], eCode);
//---------------------------------------------
// When the application is finished sending, close the socket.
setupStatus=false;
printf("Finished sending. Closing socket.\n");
iResult = closesocket(connUDP);
if (iResult == SOCKET_ERROR)
{
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return false;
}
//---------------------------------------------
// Clean up and quit.
printf("Exiting.\n");
WSACleanup();
return true;
}
void SocketClient::receiveDataThreadV(SocketClient* ptr)
{
while(true)
{
ptr->recvBufLen=recvfrom(ptr->connUDP, ptr->recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & ptr->UDPsendAddr, &ptr->addrSize);
if (ptr->recvBufLen == SOCKET_ERROR)
{
wprintf(L"recv failed with error %d\n", WSAGetLastError());
}
//ptr->buffer[ptr->iResult]='\0';
else
ptr->parseReceivedData();
}
}
void SocketClient::receiveDataWaitOnResponse()
{
recvBufLen=recvfrom(connUDP, recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & UDPsendAddr, &addrSize);
if (recvBufLen == SOCKET_ERROR)
{
wprintf(L"recv failed with error %d\n", WSAGetLastError());
}
//buffer[iResult]='\0';
else
parseReceivedData();
}
void SocketClient::sendDataThreadV(SocketClient* ptr)
{
printf("NOT YET IMPLEMENTED");
/*while(ptr->connectStatus)
{
memcpy(ptr->dataBuf+1,&ptr->playerContPtr->getPlayerData(),playerDataSize);
ptr->sendData(ptr->dataBuf, playerDataSize+1);
Sleep(ptr->sendDelayMS);
}*/
}
#endif

View File

@ -0,0 +1,147 @@
#pragma once
//Start by defining unicode
//#ifndef UNICODE
//#define UNICODE
//#endif
//defining WIN32_LEAN_AND_MEAN this early is REQUIRED if you want to avoid a certain winsock error.
//#define WIN32_LEAN_AND_MEAN
//#define NOMINMAX
//#include
//#include "GameClassExample.h"
//These includes are required for winsock
#include "Network.h"
//#include <winsock2.h>
//#include <Ws2tcpip.h>
//#include <stdio.h>
//#include <windows.h>
//#include "OysterMath.h"
//These are optional includes for various useful features
#include <time.h>
#include <string>
#include <ctime>
#include <iostream>
//ws2_32.lib is a lib file the linker requires for winsock compilation
#pragma comment(lib, "Ws2_32.lib")
//constants used by the socket client to avoid hard coding and/or mass variable declaration
const short TCPSendPort = 11110;
const short TCPRecvPort = 11111;
const short UDPSendPort = 11000;
const short UDPRecvPort = 11001;
const int BUFFER_MAX_SIZE = 4096;
enum ConnectionStatus
{
OFFLINE,
ONLINE_MAINMENU,
ONLINE_QUEUEING,
ONLINE_INLOBBY,
ONLINE_INGAME
};
class SocketClient
{
private:
HANDLE threadhandle[2];
int sendDelayMS;
//2 bools used to verify the activation of the client so threads can't start too early
ConnectionStatus connStatus;
bool setupStatus;
bool connectStatus;
//iResult is used to check error codes
int iResult;
//wsaData records error messages and errors which winsock might encounter
WSADATA wsaData;
//Main socket
SOCKET connUDP;
SOCKET connTCP;
//Addresses used for data transfer
sockaddr_in TCPrecvAddr;
sockaddr_in TCPsendAddr;
//UDPrecvAddr marks the port and IP adress the server is supposed to return data to.
sockaddr_in UDPrecvAddr;
//UDPsendAddr marks which IP and port the client is supposed to send data to.
sockaddr_in UDPsendAddr;
//size of a sockaddr_in. This might as well be a constant, but i'm keeping it in the class for performance reasons.
int addrSize;
//buffer which is filled when data receive happens.
char* recvBuffer;
//this variable tracks the buffer length.
int recvBufLen;
//dataBuf is a buffer solely for sending your own user data. It never changes size in order to increase performance.
//char* sendBuffer;
//int sendBufLen;
//PlayerStruct tmpPlayer;
char* dataBuf;
int playerDataSize;
public:
void setPlayerDataSize(int pds){playerDataSize=pds;}
//Constructor
SocketClient();
//Initiation for sockets.
bool init(int listenPort);
bool initTCPSocket(int listenPort);
bool initUDPSocket(int listenPort);
//Connects to a server of a user-defined IP. Can only be called after an initXSocket has gone through.
//The 2 remaining variables are init data and size of said data. Currently username.
bool connectToIP(const char* ip, int listenPort, char* initData, int initDataSize);
//sends an undefined data type of (variable#2) size to the server.
bool sendDataUDP(const char*, int);
bool sendDataTCP(const char*, int);
//sends a text string to the server.
bool sendMessage(std::string str);
bool sendServerMessage(std::string str);
//sends user data to the server
bool sendUserData();
bool sendUserData(char* data, int size);
//Closes connection, kills off the socket.
bool closeConnection();
//Simple ifBoolIsTrue checks
bool isReady() const {return setupStatus;}
bool isConnected() const {return connectStatus;}
void receiveDataWaitOnResponse();
//Sends data periodically
static void sendDataThreadV(SocketClient* ptr);
//Receive loop. This is event-based and is on its own thread.
static void receiveDataThreadV(SocketClient* ptr);
//Once data is received, it calls on the parseReceivedData function.
void parseReceivedData();
//void parseReceivedKeyframe();
//If an event is called from the server, this function will be called.
void parseReceivedEvent();
void parseReceivedEffect();
//It is then sent to one of the following functions based on the first byte of the buffer.
//Servermessage
void parseServermessage();
//single user data
void parseData();
//string (character data)
void parseMessage();
//init data which sets the start position etc of all characters.
void parseLobbyInitData();
void parseGameInitData();
void parseRenderData();
bool startReceiveThread();
bool startSendDataThread();
void setSendDelay(int ms){sendDelayMS=ms;}
//virtual functions
virtual void receiveGameInitData(char*)=0;
virtual void receiveLobbyInitData(char*, int)=0;
virtual void receivePlayerUpdate(char*, int)=0;
virtual void receiveRenderData(char*, int)=0;
virtual void receiveEffectData(char*, int)=0;
virtual void receiveConnStatus(ConnectionStatus)=0;
virtual void receiveEvent(char*)=0;
};

View File

@ -0,0 +1,113 @@
#include "Game.h"
Game::Game()
{
playerCount=0;
started=false;
for (int i=0; i<MUTEX_COUNT; i++)
{
mutex[i] = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
NULL); // unnamed mutex
if (mutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
}
}
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
ready[i]=false;
}
}
/*bool Game::checkMoveValidity(ClientToServerUpdateData plr)
{
if (false)
{
players[plr.pid]=plr;
return true;
} else
{
//The package that arrived is an earlier version than the last one.
//Ignore the position data, but still check actions and such to make
//sure that you don't miss a key press.
//For example, if the fire button is true in this package but false now,
//the ship should still shoot once.
return true;
}
}
Float4x4 Game::getPlayerPos(int id)
{
WaitForSingleObject(mutex[0], INFINITE);
Float4x4 tmp=players[id].position;
ReleaseMutex(mutex[0]);
return tmp;
}
void Game::setPlayerPos(int id, Float4x4 pos)
{
WaitForSingleObject(mutex[0], INFINITE);
players[id].position=pos;
ReleaseMutex(mutex[0]);
}
ClientToServerUpdateData Game::getPlayerData(int id)
{
WaitForSingleObject(mutex[0], INFINITE);
ClientToServerUpdateData tmp=players[id];
ReleaseMutex(mutex[0]);
return tmp;
}
void Game::setPlayerData(int id, ClientToServerUpdateData ps)
{
WaitForSingleObject(mutex[0], INFINITE);
players[id]=ps;
ReleaseMutex(mutex[0]);
}*/
void Game::initGame(std::vector<User> usr, int nrOfPlayers)
{
/*for (int i=0; i<nrOfPlayers; i++)
{
users[i]=&usr[i];
}*/
Oyster::Math::Float4x4 initvariable=Oyster::Math::Float4x4::identity;
initvariable.v[3].x=50;
for (unsigned int i=0; i<PLAYER_MAX_COUNT; i++)
{
initvariable.v[3].x=(Float)200*i;
//players[i].position=initvariable;
}
//players[1].position.m11=0.1f;
//players[1].position.m22=0.1f;
//players[1].position.m33=0.1f;
}
GameInitData Game::getInitData()
{
//Later getInitData will need to receive a user id to set it up 100%.
//That way, this is the only function that needs to be called in order to connect(or reconnect) to a game.
GameInitData init;
init.pid=0;
for (unsigned int i=0; i<PLAYER_MAX_COUNT; i++)
{
init.player[i].pid=i;
init.player[i].teamid=i%2;
//init.player[i].position=getPlayerPos(i);
//users[i]->setGame(2);
//init.players[i]=players[i];
}
return init;
}
void Game::addUser(int uid)
{
userID[playerCount++]=uid;
}
bool Game::startGame()
{
started=true;
return started;
}
void Game::update(float dt)
{
}

View File

@ -0,0 +1,51 @@
#pragma once
#ifndef GAME_H
#define GAME_H
#include "User.h"
#include "ServerInclude.h"
const int MUTEX_COUNT =2;
//Mutex #0=playerPos setGet
//Mutex #1=
//#include "Session.h"
class Game
{
private:
bool started;
//ClientToServerUpdateData players[PLAYER_MAX_COUNT];
User* users[PLAYER_MAX_COUNT];
int userID[PLAYER_MAX_COUNT];
bool ready[PLAYER_MAX_COUNT];
int playerCount;
//Tracks which ship each user has
int shipID[PLAYER_MAX_COUNT];
HANDLE mutex[MUTEX_COUNT];
//::Game::Session *session;
int sessionID;
public:
//Will reset all data
//playerIDs is an array of int which points toward each users connection.
void setReady(int pid, bool rdy){ready[pid]=rdy;}
bool allReady(){for (int i=0; i<playerCount; i++){if(ready[i]==false)return false;}return true;}
void initGame(std::vector<User> players, int nrOfPlayers);
GameInitData getInitData();
bool startGame();
bool isStarted(){return started;}
Game();
//Float4x4 getPlayerPos(int id);
//void setPlayerPos(int id, Float4x4 pos);
//bool checkMoveValidity(ClientToServerUpdateData plr);
//ClientToServerUpdateData getPlayerData(int id);
//void setPlayerData(int id, ClientToServerUpdateData ps);
int getPlayerCount() {return playerCount;}
int getUserID(int i) {return userID[i];}
void initLUA(char* file);
void update(float dt);
void addUser(int uid);
void removeUser(int uid){playerCount--;}
};
#endif

View File

@ -0,0 +1,73 @@
#include "Lobby.h"
Lobby::Lobby()
{
timerStarted=false;
nrUsers=0;
timerMutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
NULL); // unnamed mutex
if (timerMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
}
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
userData[i].pid=i;
userData[i].shipID=0;
userData[i].usrName[0]='\0';
//userData[i].usrName="Player";
//userData[i].usrName+=(char)i;
}
}
void Lobby::removeUser()
{
}
void Lobby::addUser(User usr, int i)
{
userID[nrUsers]=i;
userData[nrUsers].setName(usr.getUsername().c_str());
//userData[nrUsers].shipID=1;
nrUsers++;
}
void Lobby::updateUserData(LobbyUserStruct data)
{
userData[data.pid]=data;
}
LobbyInitData Lobby::getLobbyInitData()
{
LobbyInitData data;
data.playerCount=nrUsers;
for(int i=0; i<PLAYER_MAX_COUNT; i++)
{
data.players[i]=userData[i];
}
return data;
}
void Lobby::startLobbyCountdown(float seconds)
{
WaitForSingleObject(timerMutex, INFINITE);
countdownLimit=seconds;
countdownTimer.reset();
countdownTimer.start();
timerStarted=true;
ReleaseMutex(timerMutex);
}
float Lobby::timeLeft()
{
WaitForSingleObject(timerMutex, INFINITE);
countdownTimer.tick();
if (!timerStarted)
return -1;
else
{
float timeLeft=countdownLimit-countdownTimer.getGameTime();
if(timeLeft>0)
return timeLeft;
else
return 0;
}
ReleaseMutex(timerMutex);
}

View File

@ -0,0 +1,27 @@
#include "ServerInclude.h"
#include "User.h"
#ifndef LOBBY_H
#define LOBBY_H
class Lobby
{
private:
int nrUsers;
int userID[PLAYER_MAX_COUNT];
ServerTimer countdownTimer;
float countdownLimit;
LobbyUserStruct userData[PLAYER_MAX_COUNT];
bool timerStarted;
HANDLE timerMutex;
public:
Lobby();
void addUser(User usr, int i);
int getUserID(int i) const {return userID[i];}
int getNrPlayers() const {return nrUsers;}
void removeUser();
void updateUserData(LobbyUserStruct);
LobbyInitData getLobbyInitData();
void startLobbyCountdown(float seconds);
float timeLeft();
};
#endif

View File

@ -0,0 +1,219 @@
#include "SocketServer.h"
void SocketServer::parseReceivedData(int threadID/*char* data, int size*/)
{
bool test=false;
for(unsigned int i=0; i<users.size(); i++)
{
if(memcmp(&connData[threadID].srcAddr, &users[i].getAddr(), sizeof(sockaddr_in)) != 0)
{
//User i has not sent the data.
test=false;
}
else
{
//Found the user which sent the data
test=true;
switch (connData[threadID].buffer[0])
{
case 1://It's data
if(users[i].isIngame()) parseData(i, users[i].getGame(), threadID);
break;
case 2://It's a user-entered command
parseServercommand(i, threadID);
break;
case 3://It's a chat message
parseMessage(i, threadID);
break;
}
break;
}
}
if(!test)
{
//User does not exist yet
//This is temporary until i have a proper login process in place
addUser(threadID);
}
}
void SocketServer::addUser(int threadID)
{
printf("UDP adding user.\n");
User usr=User((int)users.size(),connData[threadID].srcAddr);
connData[threadID].buffer[connData[threadID].dataSize]='\0';
usr.setUsername(connData[threadID].buffer);
users.push_back(usr);
sendData(((int)users.size())-1, "\4connected",10);
std::string asd=users[users.size()-1].getUsername();
printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
}
void SocketServer::AddUser(ConnThreadData* data)
{
printf("TCP adding user.\n");
User usr=User((int)users.size(),data->srcAddr);
data->buffer[data->dataSize]='\0';
usr.setUsername(data->buffer);
users.push_back(usr);
sendData(((int)users.size())-1, "\4connected",10);
std::string asd=users[users.size()-1].getUsername();
printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
}
void SocketServer::removeUser(int id)
{
games[users[id].getGame()].removeUser(id);
users.erase(users.begin()+id);
}
void SocketServer::parseServercommand(int pid, int threadID)
{
connData[threadID].buffer[connData[threadID].dataSize]='\0';
wprintf(L"User %d sent a server command.\n", pid);
printf("The command is the following:%s.\n", connData[threadID].buffer+1);
std::vector<std::string> list=splitString(connData[threadID].buffer+1, ' ');
bool validcommand=false;
if(list.size()==0)
{
//Ignore case 1, to avoid vector subscript out of range errors
}
//First variable: Command
else if(!list[0].compare(" "))
{
//Add rest ignore cases here
}
else if(!list[0].compare("help"))
{
validcommand=true;
}
//else if(!list[0].compare("startgame"))
//{
//validcommand=true;
//Do more than just sending init data here
//sendInitData();
//}
else if (!list[0].compare("exit"))
{
validcommand=true;
//User #pid needs to be removed here, and data needs to be sorted accordingly.
}
else if (!list[0].compare("qst"))
{
validcommand=true;
if (users[pid].getState()==ONLINE)
{
sendData(pid, "\4qst",4);
users[pid].setState(ONLINE_QUEUEING);
}
}
else if (!list[0].compare("qed"))
{
validcommand=true;
if (users[pid].getState()==ONLINE_QUEUEING)
{
sendData(pid, "\4qed",4);
users[pid].setState(ONLINE);
}
}
else if (!list[0].compare("rdy"))
{
if (users[pid].getState()==ONLINE_INGAME)
{
games[users[pid].getGame()].setReady(pid, true);
}
}
else if (!list[0].compare("dc"))
{
validcommand=true;
printf("User %s (ID:%d) has disconnected.",users[pid].getUsername().c_str(), pid);
users[pid].setState(OFFLINE);
removeUser(pid);
//Tell games that he might be in here taht he's down
//users.erase(users.begin()
}
else if((!list[0].compare("w")||!list[0].compare("whisper")||!list[0].compare("msg")) && list.size()>2)
{
validcommand=true;
for(unsigned int i=0; i<users.size(); i++)
{
//Second variable: Target user
if (!list[1].compare(users[i].getUsername()))
{
//Other variables: Text message.
//The +3 is for the 2 spaces and the first /. Calculating the start pos of the message.
int startloc=(int)(list[0].length()+list[1].length())+3;
//std::string msg="\3[Whisper] "+users[pid].getUsername()+":"+(connData[threadID].buffer+startloc);
//msg+=users[pid].getUsername()
//sendData(i,msg.c_str(), msg.length());
}
}
}
else if(!list[0].compare("setname"))
{
if(list.size()>1)
{
users[pid].setUsername(list[1]);
//list[1]="\3Your username has been changed to "+list[1];
//sendData(pid,list[1].c_str(), list[1].length());
validcommand=true;
}
}
if(!validcommand)
{
int a=0;
//sendData(pid, "\3Invalid server command.", 24);
//Tell user that the server command was invalid
}
}
void SocketServer::parseData(int pid, int gid, int threadID)
{
memcpy(&connData[threadID].tmpdata,connData[threadID].buffer+1,CLIENT_PLAYER_DATA_SIZE);
//No old packets
if (users[pid].getLastUpdate()<connData[threadID].tmpdata.updateCount)
{
users[pid].setLastUpdate(connData[threadID].tmpdata.updateCount);
users[pid].setLastUpdateData(connData[threadID].tmpdata);
ControlPlayer(session->accessPlayer(pid),connData[threadID].tmpdata);
}
}
void SocketServer::parseMessage(int pid, int threadID)
{
std::string message;
message="\3[Chat] "+users[pid].getUsername()+": "+(connData[threadID].buffer+1);
sendData(-1,message.c_str(), (int)message.length());
}
void SocketServer::sendInitData(int gid)
{
GameInitData init=games[gid].getInitData();
//int test=session->getNumPlayers(); // getNumPlayers is removed
for (int i=0; i<PLAYER_MAX_COUNT; i++)
{
init.player[i].position=session->accessPlayer(i).getOrientation();
}
char* gd=new char[sizeof(init)+1];
gd[0]=2;
for (int i=0; i<games[gid].getPlayerCount(); i++)
{
int c=sizeof(init);
init.pid=i;
memcpy(gd+1,&init, sizeof(init));
sendData(games[gid].getUserID(i), gd, sizeof(init)+1);
}
}
void SocketServer::sendLobbyInitData(int lid)
{
LobbyInitData init=lobby.getLobbyInitData();
init.timer=LOBBY_WAIT_TIME;
int c=sizeof(init);
char* gd=new char[c+1];
gd[0]=5;
for (int i=0; i<lobby.getNrPlayers(); i++)
{
init.pid=i;
memcpy(gd+1,&init, c);
sendData(lobby.getUserID(i), gd, c+1);
}
}

View File

@ -0,0 +1,19 @@
#include "Network.h"
#pragma once
#ifdef _DEBUG
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
#else
#define DEBUG_NEW new
#endif
#include <vector>
#include <time.h>
#include <string>
#include <sstream>
#include "OysterMath.h"
#include "Session.h"
#include "ServerTimer.h"
using namespace Network;
const float GAME_UPDATEDELAY=1.0f/120.0f;

View File

@ -0,0 +1,47 @@
#include <ctime>
#include "SocketServer.h"
#include "ServerTimer.h"
#include <iostream>
#include <string>
#include <stdio.h>
//#ifdef WINDOWS
#include <direct.h>
#include "ServerInclude.h"
#define GetCurrentDir _getcwd
//#else
//For other OS than windows; can't be found on
//all windows setups so it's commented for now
//#include <unistd.h>
//#define GetCurrentDir getcwd
//#endif
char* getCurDir()
{
char* cCurrentPath;
cCurrentPath=new char[FILENAME_MAX];
int test=sizeof(cCurrentPath);
if (!GetCurrentDir(cCurrentPath, FILENAME_MAX))
{
return "ERROR";
}
cCurrentPath[FILENAME_MAX - 1] = '\0';
return cCurrentPath;
}
int main(int argc, char *argv[])
{
srand((unsigned int)time(0));
::Oyster::Game::MoveAble::setDiscreteTimeSlice( GAME_UPDATEDELAY );
SocketServer server;
server.loadMapList("..\\Content\\Maplist.txt");
while (!server.isReady());
server.startThreads();
GameLogic::Object::init("NOT_IMPLEMENTED");
server.startGameCreateLoop(50);
while(true)
{
server.updateServers();
}
server.closeConnection();
return 0;
}

View File

@ -0,0 +1,66 @@
#include "SocketServer.h"
bool SocketServer::initTCPSocket()
{
//----------------------
// Create a SOCKET for listening for incoming connection requests.
TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (TCPSocket == INVALID_SOCKET) {
wprintf(L"TCP socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return false;
}
iResult = bind(TCPSocket, (SOCKADDR *) & TCPRecvAddr, addrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"TCP bind function failed with error %d\n", WSAGetLastError());
iResult = closesocket(TCPSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"TCP closesocket function failed with error %d\n", WSAGetLastError());
WSACleanup();
return false;
}
return true;
}
DWORD SocketServer::activateTCPConnectLoop(ThreadArguments* tra)
{
while (true)
{
(tra->ptr)->receiveConnection(tra->threadID);
}
}
void SocketServer::receiveConnection(int threadID)
{
User tmp;
//----------------------
// Listen for incoming connection requests
// on the created socket
if (listen(TCPSocket, SOMAXCONN) == SOCKET_ERROR)
{
wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
return;
}
printf("Starting TCP connection loop.\n");
int a=0;
while(a==0)
{
a=1;
tmp.connection=accept(TCPSocket, (struct sockaddr*)&TCPRecvAddr, &addrSize);
printf("Accepted a TCP connection from IP %s.\n", inet_ntoa(TCPRecvAddr.sin_addr));
tcpData[threadID].dataSize=recv(
tmp.connection,
tcpData[threadID].buffer,
tcpData[threadID].bufLen,
0);
connData[threadID].buffer[connData[threadID].dataSize]='\0';
tmp.setUsername(tcpData[threadID].buffer);
if (tcpData[threadID].dataSize == SOCKET_ERROR)
{
wprintf(L"TCP recv failed with error %d\n", WSAGetLastError());
}
printf("TCP Thread #%d received connData from %s\n", threadID, inet_ntoa(tcpData[threadID].srcAddr.sin_addr));
//connData[threadID].buffer[connData[threadID].dataSize]='\0';
//AddUser(&tcpData[threadID]);
//parseReceivedData(threadID);
}
}

View File

@ -0,0 +1,85 @@
#include "ServerTimer.h"
ServerTimer::ServerTimer()
:
c_SecondsPerCount(0.0),
c_DeltaTime(-1.0),
c_BaseTime(0),
c_PausedTime(0),
c_PrevTime(0),
c_CurrTime(0),
c_Stopped(false)
{
__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
c_SecondsPerCount =1.0 / (double)countsPerSec;
QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
}
void ServerTimer::start()
{
__int64 p_StartTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
if(c_Stopped)
{
c_PausedTime += (p_StartTime-c_StopTime);
c_PrevTime = p_StartTime;
c_StopTime = 0;
c_Stopped = false;
}
}
__int64 ServerTimer::getTime()
{
__int64 testInt;
return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
return testInt;
}
void ServerTimer::stop()
{
if(!c_Stopped)
{
__int64 p_CurrTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
c_StopTime = p_CurrTime;
c_Stopped = true;
}
}
void ServerTimer::reset()
{
__int64 p_CurrTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
c_BaseTime = p_CurrTime;
c_PrevTime = p_CurrTime;
c_StopTime = 0;
c_Stopped = false;
}
void ServerTimer::tick()
{
if (c_Stopped)
{
c_DeltaTime= 0.0;
return;
}
__int64 p_CurrTime;
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
c_CurrTime=p_CurrTime;
c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
c_PrevTime=c_CurrTime;
if(c_DeltaTime<0.0) c_DeltaTime=0.0;
}
float ServerTimer::getGameTime() const
{
if(c_Stopped)
{
return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
} else
{
return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
}
}
float ServerTimer::getDeltaTime() const
{
return (float)c_DeltaTime;
}

View File

@ -0,0 +1,25 @@
#include "ServerInclude.h"
#ifndef _GAME_TIMER_H
#define _GAME_TIMER_H
class ServerTimer
{
private:
double c_SecondsPerCount;
double c_DeltaTime;
__int64 c_BaseTime;
__int64 c_PausedTime;
__int64 c_StopTime;
__int64 c_PrevTime;
__int64 c_CurrTime;
bool c_Stopped;
public:
ServerTimer();
__int64 getTime();
void start();
void stop();
void reset();
void tick();
float getGameTime() const;
float getDeltaTime() const;
};
#endif

View File

@ -0,0 +1,55 @@
#include "SocketServer.h"
bool SocketServer::initUDPSocket()
{
//---------------------------------------------
// Create a socket for sending data
UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (UDPSocket == INVALID_SOCKET) {
wprintf(L"UDP socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return false;
}
//---------------------------------------------
// Bind socket to IP
iResult = bind(UDPSocket, (SOCKADDR *) & UDPRecvAddr, addrSize);
if (iResult == SOCKET_ERROR) {
wprintf(L"UDP bind failed with error: %d\n", WSAGetLastError());
closesocket(UDPSocket);
WSACleanup();
return false;
}
return true;
}
DWORD SocketServer::activateUDPReceiveLoop(ThreadArguments* tra)
{
(tra->ptr)->serverUDPReceiveLoopActive=true;//weird crash //PAR
(tra->ptr)->receiveDataUDP(tra->threadID);
return 0;
}
void SocketServer::stopUDPReceiveLoops()
{
serverUDPReceiveLoopActive=false;
WaitForMultipleObjects(NR_CONNECTTHREADS, udpDataHandle, true, INFINITE);
printf("All UDP data recv threads stopped.\n");
}
void SocketServer::receiveDataUDP(int threadID)
{
while(serverUDPReceiveLoopActive)
{
connData[threadID].dataSize=recvfrom(
UDPSocket,
connData[threadID].buffer,
connData[threadID].bufLen,
0,
(SOCKADDR *)&connData[threadID].srcAddr,
&addrSize);
if (connData[threadID].dataSize == SOCKET_ERROR)
{
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
}
//printf("Thread #%d received data from %s\n", threadID, inet_ntoa(connData[threadID].srcAddr.sin_addr));
//connData[threadID].buffer[connData[threadID].dataSize]='\0';
else
parseReceivedData(threadID);
}
}

View File

@ -0,0 +1,420 @@
#include "SocketServer.h"
#include <fstream>
bool SocketServer::loadMapList(char* maploc)
{
::std::string workDir;
::Utility::String::extractDirPath( workDir, maploc, '\\' );
//maploc is the filename of the list which contains all maps
//load all map file names into the server, but don't load the maps themselves.
std::ifstream file;
file.open(maploc);
if (!file.is_open())
return false;
::std::string str;
while(!file.eof())
{
::std::getline( file, str );
maps.push_back( workDir + str );
}
/*
maps.push_back("map1test.map");
maps.push_back("map2 test.map");
*/
return true;
}
bool SocketServer::LoadInitData(char* maploc)
{
std::vector<std::string> cont;
char* in=new char[100];
std::ifstream ifs;
ifs.open(maploc);
if(!ifs.is_open())
{
return false;
}
while(!ifs.eof())
{
ifs.getline(in, 100);
cont=splitString(in, '=');
if (cont.size()==2)
{
if(!strcmp("nr_players_per_session", cont[0].c_str()))
{
playersPerSessionCount=atoi(cont[1].c_str());
}
else if(!strcmp("nr_kills_to_win", cont[0].c_str()))
{
killsRequiredPerSession=atoi(cont[1].c_str());
}
else if(!strcmp("match_type", cont[0].c_str()))
{
//Isn't used
}
}
}
ifs.close();
}
SocketServer::~SocketServer()
{
serverTCPConnectionLoopActive=false;
serverUDPReceiveLoopActive=false;
serverTCPReceiveLoopActive=false;
for (int i=0; i<NR_CONNECTTHREADS; i++)
{
delete connData[i].buffer;
}
for (int i=0; i<NR_SIMULTCPCONNECTS; i++)
{
delete tcpData[i].buffer;
}
delete sendGameDataBuffer;
delete sendEffectDataBuffer;
closeConnection();
}
void SocketServer::startGameCreateLoop(int delay)
{
lobbyActive=false;
DEBUGCTR=0;
if(!serverGameCreationActive)
{
ThreadArguments tr;
tr.ptr=this;
tr.threadID=delay;
serverGameCreationActive=true;
gameCreateHandle=CreateThread(
NULL, //Choose default security
0, //Default stack size
(LPTHREAD_START_ROUTINE)&activateServerGameLoop,
//Routine to execute
(LPVOID) &tr, //Thread parameter
0, //Immediately run the thread
0 //Thread Id
);
if (gameCreateHandle == NULL)
{
printf("Game creation thread ERROR");
}
else
{
printf("Game creation thread successful\n");
Sleep(100);
}
}
}
void SocketServer::stopGameCreateLoop()
{
serverGameCreationActive=false;
WaitForSingleObject(gameCreateHandle, INFINITE);
printf("Game Creation thread ended.\n");
}
DWORD SocketServer::activateServerGameLoop(ThreadArguments* tra)
{
srand((unsigned int)(time(0)));
(tra->ptr)->serverGameCreationLoop(tra->threadID);
return 0;
}
bool SocketServer::serverGameCreationLoop(int delay)
{ // TODO: Mem access Violoation Crash 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ... delay = -858993460
//Mem access violation in a thread can also be caused by failure from something else instead of it,
//it still breaks at header even if, for example, server->load or lobby.startLobbyCountdown breaks it
//If you get an error here, make sure that isn't the problem.
int count;
while(serverGameCreationActive)
{
if (nrActiveSessions==0)
{
count=0;
for (unsigned int i=0; i<users.size(); i++)
{
if (users[i].getState()==ONLINE_QUEUEING)
{
count++;
}
}
if (count>=playersPerSessionCount)
{
games.resize(1);
//lobby.resize(games.size()+1);
session =new GameLogic::Session();
lobby = Lobby();
timer.resize(1);
timeTillUpdate.resize(1);
timeTillUpdate[0]=GAME_UPDATEDELAY;
updateCount.resize(1);
updateCount[0]=0;
int curID=(int)games.size()-1;
int mapid=rand()%maps.size();
session->setNrPlayers(playersPerSessionCount);
session->setKillsRequired(killsRequiredPerSession);
session->load(maps[mapid]);
printf("Map nr %d loaded, name %s.\n",mapid, maps[mapid].c_str());
count=0;
for (unsigned int i=0; count<playersPerSessionCount && i<users.size(); i++)
{
if (users[i].getState()==ONLINE_QUEUEING)
{
//Set to INLOBBY and send lobby data, then start a lobby
lobby.addUser(users[i], i);
users[i].setState(ONLINE_INGAME);
games[curID].addUser(i);
users[i].setGame(curID);
session->accessPlayer(i).spawn();
count++;
}
}
lobbyActive=true;
sendLobbyInitData(curID);
lobby.startLobbyCountdown(LOBBY_WAIT_TIME);
sendRenderData(curID);
//return true;
}
if(lobbyActive)
{
for (int i=0; i<1; i++)
{
float ttimer=lobby.timeLeft();
if (ttimer==0)
{
printf("Starting game.\n");
games[i].initGame(users,playersPerSessionCount);
sendInitData(i);
nrActiveSessions++;
lobbyActive=false;
//serverGameCreationActive=false;
}
}
}
}
Sleep(delay);
}
printf("Maximum server count reached, shutting down the sever creation thread.\n");
return false;
}
SocketServer::SocketServer()
{
UDPSocket = INVALID_SOCKET;
nrActiveSessions=0;
serverGameCreationActive=false;
serverTCPConnectionLoopActive=false;
serverTCPReceiveLoopActive=false;
serverUDPReceiveLoopActive=false;
killsRequiredPerSession=10;
playersPerSessionCount=1;
LoadInitData("../ServerData.dat");
//---------------------------------------------
// Set up the port and IP of the server
//Port starts up as a different one from when UDPSocketected, it changes once the server has exchanged some info with the client
UDPRecvAddr.sin_family = AF_INET;
UDPRecvAddr.sin_port = htons(UDPRecvPort);
UDPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
sessionEvents=std::vector<Event::GameEvent*>(0);
sessionEffects=std::vector<Network::EffectData>(0);
TCPRecvAddr.sin_family = AF_INET;
TCPRecvAddr.sin_port = htons(TCPRecvPort);
TCPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
addrSize=sizeof(sockaddr_in);
for (int i=0; i<NR_CONNECTTHREADS; i++)
{
connData[i].buffer=new char[256];
connData[i].bufLen=256;
ZeroMemory(connData[i].buffer,sizeof(connData[i].buffer));
connData[i].dataSize=0;
//connData[i].srcAddr
memcpy(&connData[i].srcAddr, &UDPRecvAddr,addrSize);
}
for (int i=0; i<NR_SIMULTCPCONNECTS; i++)
{
tcpData[i].buffer=new char[256];
tcpData[i].bufLen=256;
ZeroMemory(tcpData[i].buffer,sizeof(tcpData[i].buffer));
tcpData[i].dataSize=0;
memcpy(&connData[i].srcAddr, &TCPRecvAddr,addrSize);
}
sendGameDataBufferSize=SERVER_PLAYER_DATA_SIZE*playersPerSessionCount+1;
sendGameDataBuffer=new char[sendGameDataBufferSize];
sendGameDataBuffer[0]=1;
sendEffectDataBuffer=new char[sizeof(Network::EffectData)+1];
sendEffectDataBuffer[0]=7;
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
}
else
{
//Init sockets
setupStatus=initTCPSocket();
if(setupStatus)
setupStatus=initUDPSocket();
}
}
bool SocketServer::startThreads()
{
//ThreadArguments tra1[NR_SIMULTCPCONNECTS];
ThreadArguments tra2[NR_CONNECTTHREADS];
//for (int i=0; i< NR_SIMULTCPCONNECTS; i++)
//{
// tra1[i].ptr=this;
// tra1[i].threadID=i;
// //printf("i - %d\n",i);
//
// tcpDataHandle[i]=CreateThread(
// NULL, //Choose default security
// 0, //Default stack size
// (LPTHREAD_START_ROUTINE)&activateTCPConnectLoop,
// //Routine to execute
// (LPVOID) &tra1[i], //Thread parameter
// 0, //Immediately run the thread
// 0 //Thread Id
// );
// if (tcpDataHandle[i] == NULL)
// {
// printf("Error Creating TCP Thread#: %d\n",i);
// return(false);
// }
// else
// {
// printf("Successfully created TCP thread #: %d\n", i);
// Sleep(100);
// }
//}
for (int i=0; i< NR_CONNECTTHREADS; i++)
{
tra2[i].ptr=this;
tra2[i].threadID=i;
//printf("i - %d\n",i);
udpDataHandle[i]=CreateThread(
NULL, //Choose default security
0, //Default stack size
(LPTHREAD_START_ROUTINE)&activateUDPReceiveLoop,
//Routine to execute
(LPVOID) &tra2[i], //Thread parameter
0, //Immediately run the thread
0 //Thread Id
);
if (udpDataHandle[i] == NULL)
{
printf("Error Creating UDP Thread#: %d\n",i);
return(false);
}
else
{
printf("Successfully created UDP thread #: %d\n", i);
Sleep(100);
}
}
return true;
}
bool SocketServer::sendData(int uid, const char* data, int size)
{
//---------------------------------------------
// Send a datagram to a user
//uid -1 = broadcast message
if (uid<0)
{
for (unsigned int i=0; i<users.size(); i++)
{
iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[i].getAddr(), addrSize);
if (iResult == SOCKET_ERROR)
{
wprintf(L"UDP sendData(-1) sendto failed with error: %d\n", WSAGetLastError());
closesocket(UDPSocket);
WSACleanup();
return false;
}
}
}
else
{
if((unsigned)uid>=users.size())
{
//User doesn't exist
printf("UDP sendData(%d) sendto failed because the specified user does not exist\n", uid);
}
else
{
iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[uid].getAddr(), addrSize);
if (iResult == SOCKET_ERROR)
{
wprintf(L"UDP sendData(%d) sendto failed with error: %d\n", uid, WSAGetLastError());
closesocket(UDPSocket);
WSACleanup();
return false;
}
}
}
return true;
}
bool SocketServer::sendKeyFrameData(int size, const char* data)
{
for (int i=0; i<playersPerSessionCount; i++)
{
iResult = sendto(UDPSocket, data, size+1, 0, (SOCKADDR *) & users[games[0].getUserID(i)].getAddr(), addrSize);
if (iResult == SOCKET_ERROR)
{
wprintf(L"UDP keyFrameData sendto failed with error: %d\n", WSAGetLastError());
closesocket(UDPSocket);
WSACleanup();
return false;
}
}
return true;
}
bool SocketServer::checkConnection(int userID)
{
char* message="\3testmessage";
int count=
sendto(
UDPSocket,
message,
(int)strlen(message),
0,
(SOCKADDR *) & users[userID].getAddr(),
addrSize);
if (count == SOCKET_ERROR)
{
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
return false;
}
else if (count==0)
{
wprintf(L"Disconnected.\n");
return false;
}
return true;
}
bool SocketServer::closeConnection()
{
//---------------------------------------------
// When the application is finished sending, close the sockets.
setupStatus=false;
wprintf(L"Finished sending. Closing socket.\n");
iResult = closesocket(UDPSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closeUDPsocket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return false;
}
iResult = closesocket(TCPSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closeTCPsocket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return false;
}
//---------------------------------------------
// Clean up and quit.
wprintf(L"Exiting.\n");
WSACleanup();
return true;
}

View File

@ -0,0 +1,255 @@
#include "SocketServer.h"
/*// BENCHMARK BLOCK
#include "WinTimer.h"
#include <iostream>
#include <fstream>
namespace Benchmark
{
struct
{
double averageTime, totalTime, minTime, maxTime; unsigned int numSamples;
} timerData[10] = { 0.0f, 0.0f, ::std::numeric_limits<double>::max(), -::std::numeric_limits<double>::max(), 0 };
void sampleTime( const ::Utility::WinTimer &timer, unsigned char ref )
{
double elapsedTime = timer.getElapsedSeconds();
timerData[ref].totalTime += elapsedTime;
timerData[ref].minTime = ::Utility::Value::min( timerData[ref].minTime, elapsedTime );
timerData[ref].maxTime = ::Utility::Value::max( timerData[ref].maxTime, elapsedTime );
++timerData[ref].numSamples;
timerData[ref].averageTime = timerData[ref].totalTime / (double) timerData[ref].numSamples;
}
void print( )
{
::std::ofstream file;
file.open( "BenchMarkData.txt", ::std::ios_base::app | ::std::ios_base::out );
if( file.is_open() )
{
file << "minTime\t\t: maxTime\t: averageTime\t\ttotalTime\tnumSamples\n";
for( unsigned char i = 0; i < 1; ++i )
file << timerData[i].minTime << (timerData[i].minTime == 0.0f ? "\t\t: " : "\t: ") << timerData[i].maxTime << "\t: " << timerData[i].averageTime << "\t\t" << timerData[i].totalTime << '\t' << timerData[i].numSamples <<'\n';
file << ::std::endl;
file.close();
::std::cout << "Benchmark data saved." << ::std::endl;
}
}
}
// END BENCHMARK BLOCK/**/
void SocketServer::updateServers()
{
for(int i=0; i<nrActiveSessions; i++)
{
if(games[i].allReady())
{
timer[i].tick();
//printf("%f seconds since last update\n", timer[i].getDeltaTime());
//printf("%f seconds since the timer started\n", timer[i].getGameTime());
//timeTillUpdate[i]-=timer[i].getDeltaTime();
DEBUGCTR++;
//Sleep(timeTillUpdate[i]*1000);
// BENCHMARK BLOCK
//::Utility::WinTimer processTimer;
// END BENCHMARK BLOCK
switch( session->update( timer[i].getDeltaTime() ) )
{
case ::GameLogic::Session::Updated:
// BENCHMARK BLOCK
//processTimer.reset();
// END BENCHMARK BLOCK
processSessionPlayerData(i);
processAllSessionEvents(i);
processAllSessionEffects(i);
// BENCHMARK BLOCK
//Benchmark::sampleTime( processTimer, 0 );
// END BENCHMARK BLOCK
DEBUGCTR=0;
updateCount[i]++;
default:
break;
case ::GameLogic::Session::Over:
processAllSessionEvents(i);
nrActiveSessions=0;
if(users.size()==0)
{
printf("Game with id %d done, shutting down the game.\n", 0);
Sleep(10);
}
break;
}
// BENCHMARK BLOCK
//if( Benchmark::timerData[0].numSamples % 1000 == 1 )
// Benchmark::print();
// END BENCHMARK BLOCK
}
}
if(nrActiveSessions==0)
{
Sleep(50);
}
}
void SocketServer::processSessionPlayerData(int serverID)
{
sendGameDataStruct.updateCount=updateCount[serverID];
int offset=1;
for (int i=0; i<playersPerSessionCount/*games[serverID].getPlayerCount()*/; i++)
{
sendGameDataStruct.position=session->accessPlayer(i).getOrientation();
sendGameDataStruct.hp=session->accessPlayer(i).getHullPoints();
sendGameDataStruct.shield=session->accessPlayer(i).getShieldPoints();
sendGameDataStruct.dirVecLen=session->accessPlayer(i).getMovement().length();
sendGameDataStruct.pid=i;
memcpy(sendGameDataBuffer+offset, &sendGameDataStruct, SERVER_PLAYER_DATA_SIZE);
offset+=SERVER_PLAYER_DATA_SIZE;
}
sendData(-1,sendGameDataBuffer, sendGameDataBufferSize);
}
void SocketServer::processAllSessionEvents(int serverID)
{
session->fetchEvents(sessionEvents);
for (int i=0; i<(int)sessionEvents.size(); i++)
{
sendEventData(serverID, i);
delete sessionEvents[i];
}
sessionEvents.resize(0);
}
bool SocketServer::sendGameData(int serverID)
{
//data[0]=1;
for (int i=0; i<games[serverID].getPlayerCount(); i++)
{
iResult = sendto(UDPSocket, sendGameDataBuffer, SERVER_PLAYER_DATA_SIZE+1, 0, (SOCKADDR *) & users[games[serverID].getUserID(i)].getAddr(), addrSize);
if (iResult == SOCKET_ERROR)
{
wprintf(L"UDP gameData sendto failed with error: %d\n", WSAGetLastError());
closesocket(UDPSocket);
WSACleanup();
return false;
}
}
return true;
}
void SocketServer::sendEventData(int gid, int sid)
{
int size=sessionEvents[sid]->GetSize();
int size1=sizeof(Event::BulletCreated);
int tst=sizeof(Event::Type);
char* ed=new char[size+1+tst];
ed[0]=6;
sessionEvents[sid]->SaveRawData(ed+(1+tst));
Event::Type eTest=Event::getEventType(sessionEvents[sid]);
memcpy(ed+1, &eTest, sizeof(Event::Type));
sendData(-1, ed, size+1+tst);
delete ed;
}
void SocketServer::sendRenderData(int gid)
{
Protocol::RenderData data;
session->writeToRenderResourceData(data);
int size=data.getRequiredBufferSize()+1;
char* sendChar=new char[size];
data.fillBuffer(sendChar+1);
sendChar[0]=8;
sendData(-1, sendChar, size);
delete sendChar;
}
void SocketServer::processAllSessionEffects(int gid)
{
session->fetchEffectData(sessionEffects);
if (sessionEffects.size()>0)
{
int size=(int)sessionEffects.size()*sizeof(Network::EffectData) + 1;
delete sendEffectDataBuffer;
sendEffectDataBuffer=new char[size];
for (size_t i=0; i<sessionEffects.size(); i++)
{
memcpy(sendEffectDataBuffer+1+sizeof(Network::EffectData)*i, &sessionEffects[i], sizeof(Network::EffectData));
//sessionEffects.
}
sendEffectDataBuffer[0]=7;
sendData(-1, sendEffectDataBuffer, size);
}
}
//HACK PLAYER UPDATE
void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update)
{
if(update.braking)
p.enableMovementReduction( true );
else
p.disableMovementReduction();
p.enableRotationReduction( true );
if(update.forward>0)
p.thrustForward();
if(update.forward<0)
p.thrustBackward();
if(update.straferight>0)
p.strafeRight();
if(update.straferight<0)
p.strafeLeft();
if(update.strafeup>0)
p.climb();
if(update.strafeup<0)
p.dive();
if(update.roll>0)
{
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
p.rollLeft();
p.rotationProperty.acceleration.roll = baseAcceleration;
}
if(update.roll<0)
{
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
p.rollRight();
p.rotationProperty.acceleration.roll = baseAcceleration;
}
if(update.roll==0)
{
p.stopRotation();
}
if(update.TurnVer!=0.0f)
{
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.pitch;
p.rotationProperty.acceleration.pitch *= -update.TurnVer / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
p.pitchUp( );
p.disableRotationReduction();
p.rotationProperty.acceleration.pitch = baseAcceleration;
}
if(update.TurnHor!=0.0f)
{
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.yaw;
p.rotationProperty.acceleration.yaw *= -update.TurnHor / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
p.yawLeft( );
p.disableRotationReduction();
p.rotationProperty.acceleration.yaw = baseAcceleration;
}
if(update.firePrim)
p.firePrimaryWeapon();
}

View File

@ -0,0 +1,126 @@
#include "Game.h"
#include "Lobby.h"
void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update);
const int NR_CONNECTTHREADS=1;
const int NR_SIMULTCPCONNECTS=1;
//threads can only take 1 argument
struct ThreadArguments;
struct ConnThreadData
{
sockaddr_in srcAddr;
ClientToServerUpdateData tmpdata;
char* buffer;
int bufLen;
int dataSize;
};
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
const short TCPSendPort = 11111;
const short TCPRecvPort = 11110;
const short UDPSendPort = 11001;
const short UDPRecvPort = 11000;
class SocketServer
{
private:
bool serverGameCreationActive;
HANDLE gameCreateHandle;
bool serverTCPConnectionLoopActive;
bool serverUDPReceiveLoopActive;
bool serverTCPReceiveLoopActive;
bool setupStatus;
int iResult;
WSADATA wsaData;
SOCKET UDPSocket;
SOCKET TCPSocket;
sockaddr_in TCPRecvAddr;
sockaddr_in UDPRecvAddr;
int addrSize;
HANDLE tcpDataHandle[NR_SIMULTCPCONNECTS];
ConnThreadData tcpData[NR_SIMULTCPCONNECTS];
HANDLE udpDataHandle[NR_CONNECTTHREADS];
ConnThreadData connData[NR_CONNECTTHREADS];
int dataSize;
char* sendEffectDataBuffer;
char* sendGameDataBuffer;
int sendGameDataBufferSize;
ServerToClientUpdateData sendGameDataStruct;
std::vector<User> users;
std::vector<Game> games;
Lobby lobby;
int nrActiveSessions;
std::vector<Event::GameEvent*> sessionEvents;
std::vector<Network::EffectData> sessionEffects;
GameLogic::Session* session;
std::vector<ServerTimer> timer;
int DEBUGCTR;
std::vector<long> updateCount;
std::vector<float> timeTillUpdate;
std::vector<::std::string> maps;
std::string text;
int playersPerSessionCount;
int killsRequiredPerSession;
bool lobbyActive;
public:
virtual ~SocketServer();
//Debug force modify functions
void processAllSessionEvents(int serverID);
void processAllSessionEffects(int gid);
void processSessionPlayerData(int serverID);
//End of debug items
void updateServers();
SocketServer();
bool checkConnection(int userID);
bool initUDPSocket();
bool initTCPSocket();
//void firstTimeConnect();
bool loadMapList(char* map);
bool serverGameCreationLoop(int delay);
bool startThreads();
static DWORD activateUDPReceiveLoop(ThreadArguments* tra);
void stopUDPReceiveLoops();
//TCP functions
static DWORD activateTCPConnectLoop(ThreadArguments* tra);
void receiveConnection(int threadID);
//End of TCP functions
bool sendData(int uid, const char*, int);
bool sendGameData(int serverID);
bool sendKeyFrameData(int size, const char* data);
void sendInitData(int gid);
void sendRenderData(int gid);
void sendEventData(int gid, int size);
void sendLobbyInitData(int lid);
bool closeConnection();
void receiveDataUDP(int threadID);
static DWORD activateServerGameLoop(ThreadArguments* tra);
void startGameCreateLoop(int delay);
void stopGameCreateLoop();
void parseReceivedData(int threadID/*char*, int*/);//char and int required if i don't want to use the class buffer
void ParseReceivedData(ConnThreadData* data);
void parseServercommand(int pid, int threadID);
void parseData(int pid, int gid, int threadID);
void parseMessage(int pid, int threadID);
void addUser(int threadID);
void AddUser(ConnThreadData* data);
void removeUser(int id);
bool isReady() const {return setupStatus;}
bool LoadInitData(char* maploc);
};
struct ThreadArguments
{
SocketServer* ptr;
int threadID;
};

View File

@ -0,0 +1,50 @@
#include "User.h"
User::User(int i, sockaddr_in add, std::string usr)
{
addr=add;
username=usr;
curGame=-1;
connection=NULL;
state=ONLINE;
lastUpdate=-1;
updMutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
NULL); // unnamed mutex
if (updMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
}
}
User::User()
{
username="";
curGame=-1;
connection=NULL;
state=ONLINE;
lastUpdate=-1;
updMutex = CreateMutex(
NULL, // default security attributes
FALSE, // initially not owned
NULL); // unnamed mutex
if (updMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
}
lastUpdateData.pid=-1;
}
void User::setLastUpdateData(Network::ClientToServerUpdateData data)
{
WaitForSingleObject(updMutex, INFINITE);
lastUpdateData=data;
ReleaseMutex(updMutex);
}
Network::ClientToServerUpdateData User::getLastUpdateData()
{
WaitForSingleObject(updMutex, INFINITE);
Network::ClientToServerUpdateData data=lastUpdateData;
ReleaseMutex(updMutex);
return data;
}

View File

@ -0,0 +1,42 @@
#include "ServerInclude.h"
#ifndef USER_H
#define USER_H
enum UserState
{
OFFLINE,
OFFLINE_INGAME,
ONLINE,
ONLINE_QUEUEING,
ONLINE_INLOBBY,
ONLINE_INGAME
};
class User
{
private:
std::string username;
int curGame;
sockaddr_in addr;
UserState state;
long lastUpdate;
HANDLE updMutex;
Network::ClientToServerUpdateData lastUpdateData;
public:
void setLastUpdateData(Network::ClientToServerUpdateData data);
Network::ClientToServerUpdateData getLastUpdateData();
void setLastUpdate(long upd){lastUpdate=upd;}
long getLastUpdate() {return lastUpdate;}
HANDLE threadHandle;
SOCKET connection;
User();
User(int id, sockaddr_in addr, std::string usr="Unknown");
//SOCKET getTCPSocket() const {return connection;}
sockaddr_in getAddr() const {return addr;}
std::string getUsername() const {return username;}
void setUsername(std::string usr){username=usr;}
void setState(UserState st){state=st;}
UserState getState(){return state;}
void setGame(int gid){curGame=gid;}
bool isIngame() {return state==ONLINE_INGAME;}
int getGame(){return curGame;}
};
#endif

View File

@ -0,0 +1,202 @@
#include "Buffer.h"
#include "Core.h"
using namespace Oyster;
Buffer::Buffer()
{
mBuffer = NULL;
}
Buffer::~Buffer()
{
SAFE_RELEASE(mBuffer);
}
HRESULT Buffer::Apply(UINT32 misc) const
{
HRESULT hr = S_OK;
switch(mType)
{
case VERTEX_BUFFER:
{
UINT32 vertexSize = mElementSize;
UINT32 offset = 0;
Oyster::Core::DeviceContext->IASetVertexBuffers(misc, 1, &mBuffer, &vertexSize, &offset );
}
break;
case INDEX_BUFFER:
{
Oyster::Core::DeviceContext->IASetIndexBuffer(mBuffer, DXGI_FORMAT_R32_UINT, 0);
}
break;
case CONSTANT_BUFFER_VS:
{
Oyster::Core::DeviceContext->VSSetConstantBuffers(misc, 1, &mBuffer);
}
break;
case CONSTANT_BUFFER_GS:
{
Oyster::Core::DeviceContext->GSSetConstantBuffers(misc, 1, &mBuffer);
}
break;
case CONSTANT_BUFFER_PS:
{
Oyster::Core::DeviceContext->PSSetConstantBuffers(misc, 1, &mBuffer);
}
break;
case CONSTANT_BUFFER_CS:
{
Oyster::Core::DeviceContext->CSSetConstantBuffers(misc,1,&mBuffer);
}
break;
default:
hr = E_FAIL;
break;
};
return hr;
}
HRESULT Buffer::Init(const BUFFER_INIT_DESC& initDesc)
{
D3D11_BUFFER_DESC bufferDesc;
mType = initDesc.Type;
switch(mType)
{
case VERTEX_BUFFER:
{
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
if(initDesc.Usage == BUFFER_STREAM_OUT_TARGET)
bufferDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT;
}
break;
case INDEX_BUFFER:
{
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
}
break;
case STRUCTURED_BUFFER:
{
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
}
break;
case CONSTANT_BUFFER_CS:
case CONSTANT_BUFFER_VS:
case CONSTANT_BUFFER_GS:
case CONSTANT_BUFFER_PS:
{
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
}
break;
default:
return E_FAIL;
break;
};
mUsage = initDesc.Usage;
mElementSize = initDesc.ElementSize;
mElementCount = initDesc.NumElements;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
if(mUsage == BUFFER_CPU_READ)
{
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ;
}
else if(mUsage == BUFFER_CPU_WRITE)
{
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
}
else if(mUsage == BUFFER_CPU_WRITE_DISCARD)
{
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
}
//Desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.MiscFlags = 0;
bufferDesc.ByteWidth = initDesc.NumElements * initDesc.ElementSize;
bufferDesc.StructureByteStride=0;
if(mType== STRUCTURED_BUFFER)
{
bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
bufferDesc.StructureByteStride=initDesc.ElementSize;
}
//set at least 16 bytes
if(bufferDesc.ByteWidth < 16)
bufferDesc.ByteWidth = 16;
HRESULT hr = S_OK;
if(initDesc.InitData)
{
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = initDesc.InitData;
data.SysMemPitch=0;
data.SysMemSlicePitch = 0;
hr = Oyster::Core::Device->CreateBuffer(&bufferDesc, &data, &mBuffer);
}
else
{
hr = Oyster::Core::Device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
}
if(FAILED(hr))
{
MessageBox(NULL, "Unable to create buffer.", "Slenda Error", MB_ICONERROR | MB_OK);
}
return hr;
}
void* Buffer::Map()
{
void* ret = NULL;
if(mUsage == BUFFER_CPU_WRITE || mUsage == BUFFER_CPU_READ || mUsage == BUFFER_CPU_WRITE_DISCARD)
{
D3D11_MAPPED_SUBRESOURCE MappedResource;
UINT32 mapType = 0;
if(mUsage == BUFFER_CPU_READ) mapType = D3D11_MAP_READ;
else if(mUsage == BUFFER_CPU_WRITE) mapType = D3D11_MAP_WRITE;
else if(mUsage == BUFFER_CPU_WRITE_DISCARD) mapType = D3D11_MAP_WRITE_DISCARD;
HRESULT hr = S_OK;
if(FAILED(hr = Oyster::Core::DeviceContext->Map(
mBuffer,
0,
(D3D11_MAP)mapType,
0,
&MappedResource)))
{
ret = NULL;
}
else
{
ret = MappedResource.pData;
}
}
return ret;
}
void Buffer::Unmap()
{
Oyster::Core::DeviceContext->Unmap( mBuffer, 0 );
}
Buffer::operator ID3D11Buffer *()
{
return this->mBuffer;
}
Buffer::operator const ID3D11Buffer *() const
{
return this->mBuffer;
}

View File

@ -0,0 +1,76 @@
#pragma once
#ifndef CoreBuffer
#define CoreBuffer
#include "Core.h"
namespace Oyster
{
class Buffer
{
public:
enum BUFFER_TYPE
{
VERTEX_BUFFER,
INDEX_BUFFER,
CONSTANT_BUFFER_VS,
CONSTANT_BUFFER_GS,
CONSTANT_BUFFER_PS,
CONSTANT_BUFFER_CS,
STRUCTURED_BUFFER,
BUFFER_TYPE_COUNT
};
enum BUFFER_USAGE
{
BUFFER_DEFAULT,
BUFFER_STREAM_OUT_TARGET,
BUFFER_CPU_WRITE,
BUFFER_CPU_WRITE_DISCARD,
BUFFER_CPU_READ,
BUFFER_USAGE_COUNT
};
struct BUFFER_INIT_DESC
{
BUFFER_TYPE Type;
UINT32 NumElements;
UINT32 ElementSize;
BUFFER_USAGE Usage;
void* InitData;
BUFFER_INIT_DESC()
{
InitData = NULL;
Usage = BUFFER_DEFAULT;
}
};
protected:
ID3D11Buffer* mBuffer;
BUFFER_TYPE mType;
BUFFER_USAGE mUsage;
UINT32 mElementSize;
UINT32 mElementCount;
public:
Buffer();
virtual ~Buffer();
HRESULT Init(const BUFFER_INIT_DESC& initDesc);
void* Map();
void Unmap();
operator ID3D11Buffer*();
operator const ID3D11Buffer*() const;
HRESULT Apply(UINT32 misc = 0) const;
ID3D11Buffer* GetBufferPointer();
UINT32 GetVertexSize();
UINT32 GetElementCount();
};
}
#endif

View File

@ -0,0 +1,164 @@
#include "Core.h"
#include "..\Window\Window.h"
using namespace Oyster;
using std::string;
//GPU
ID3D11Device *Core::Device = NULL;
//API
ID3D11DeviceContext *Core::DeviceContext = NULL;
//SwapChain
IDXGISwapChain* Core::SwapChain = NULL;
std::stringstream Log;
inline std::stringstream* AccesLog(){return &Log;}
bool Core::Init(bool SingleThreaded, bool Reference,bool ForceDX11)
{
UINT createDeviceFlags = 0;
if( SingleThreaded )
createDeviceFlags = ::D3D11_CREATE_DEVICE_SINGLETHREADED;
::D3D_DRIVER_TYPE driverType = ::D3D_DRIVER_TYPE_HARDWARE;
if(Reference)
driverType = D3D_DRIVER_TYPE_REFERENCE;
/*#if defined(DEBUG) || defined(_DEBUG)
Log << "DirectX running in debug mode.\n";
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif*/
D3D_FEATURE_LEVEL featureLevelsToTry[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
D3D_FEATURE_LEVEL initiatedFeatureLevel;
if( FAILED( ::D3D11CreateDevice( NULL, // default adapter
driverType,
NULL, // no software device
createDeviceFlags,
featureLevelsToTry, 3, // default feature level array. DX11 support assumed
D3D11_SDK_VERSION,
&Device, // device
&initiatedFeatureLevel,
&DeviceContext ) ) ) // context
{ // if failed
if( DeviceContext ) { DeviceContext->Release(); DeviceContext = NULL; } // safe cleanup
if( Device ) { Device->Release(); Device = NULL; } // safe cleanup
}
if( driverType == ::D3D_DRIVER_TYPE_HARDWARE )
Log << "D3D_DRIVER_TYPE_HARDWARE support discovered.\n";
else
Log << "D3D_DRIVER_TYPE_REFERENCE support discovered.\n";
if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_11_0 )
{
Log << "DirectX Featurelevel 11.0 supported.\n";
}
else
{
if(ForceDX11)
return false;
if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_10_1 )
{
Log << "DirectX Featurelevel 10.1 supported.\n";
}
else
{
if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_10_0 )
{
Log << "DirectX Featurelevel 10.0 supported.\n";
}
}
}
if(Device)
return true;
return false;
}
bool Core::CreateSwapChain(HWND Window, int NrofBuffers,bool MSAA_Quality,bool Fullscreen)
{
//generate static Swapchain Desc
DXGI_SWAP_CHAIN_DESC desc;
desc.OutputWindow=Window;
desc.BufferCount=NrofBuffers;
desc.Windowed=!Fullscreen;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS;
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
desc.Flags=0;
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
desc.BufferDesc.RefreshRate.Denominator=1;
desc.BufferDesc.RefreshRate.Numerator=60;
desc.BufferDesc.Height = Window::Size.bottom;
desc.BufferDesc.Width = Window::Size.left;
//Check and Set multiSampling
if(MSAA_Quality)
{
if(FAILED(Device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&desc.SampleDesc.Quality)))
{
Log<< "Failed to check multisample quality levels (MSAAQuality).\n";
return false;
}
desc.SampleDesc.Count=4;
--desc.SampleDesc.Quality;
Log << "Supported multisample quality levels (MSAAQuality): " << desc.SampleDesc.Quality+1 << "x\n";
}
else
{
desc.SampleDesc.Count=1;
desc.SampleDesc.Quality=0;
}
//Get Device Factory
::IDXGIDevice *dxgiDevice = NULL;
if( FAILED( Device->QueryInterface( __uuidof( IDXGIDevice ), (void**)&dxgiDevice ) ) )
{
Log << "Failed to Query for the GPU's dxgiDevice.\nFailed to create swapChain for the GPU.\n";
return false;
}
::IDXGIAdapter *dxgiAdapter = NULL;
if( FAILED( dxgiDevice->GetParent( __uuidof( IDXGIAdapter ), (void**)&dxgiAdapter ) ) )
{
dxgiDevice->Release();
Log << "Failed to get GPU's parent dxgiAdapter.\nFailed to create swapChain for the GPU.\n";
return false;
}
dxgiDevice->Release();
::IDXGIFactory *dxgiFactory = NULL;
if( FAILED( dxgiAdapter->GetParent( __uuidof( IDXGIFactory ), (void**)&dxgiFactory ) ) )
{
dxgiAdapter->Release();
Log << "Failed to get GPU's parent dxgiFactory.\nFailed to create swapChain for the GPU.\n";
return false;
}
dxgiAdapter->Release();
//Create SwapChain
if( FAILED( dxgiFactory->CreateSwapChain( Device, &desc, &SwapChain ) ) )
{
dxgiFactory->Release();
Log << "Failed to create swapChain for the GPU.\n";
return false;
}
dxgiFactory->Release();
return true;
}

View File

@ -0,0 +1,30 @@
#pragma once
#ifndef Core_h
#define Core_h
#include "CoreIncludes.h"
#include <sstream>
namespace Oyster
{
class Core
{
public:
static ID3D11Device* Device;
static ID3D11DeviceContext* DeviceContext;
static IDXGISwapChain* SwapChain;
static std::stringstream* AccesLog();
static bool Init(bool SingleThreaded,bool Reference,bool ForceDX11);
static bool CreateSwapChain(HWND Window, int NrofBuffers,bool MSAA_Quality,bool Fullscreen);
};
}
#endif

View File

@ -0,0 +1,40 @@
#pragma once
#ifndef CORE_INCLUDE
#define CORE_INCLUDE
#define NOMINMAX // Because I hate Microsoft now. ~Angry Dan.
// http://lolengine.net/blog/2011/3/4/fuck-you-microsoft-near-far-macros
#include <WinSock2.h>
#include <windows.h>
#include <D3D11.h>
#include <D3DX11.h>
#include <D3DX10math.h>
#include <d3dx11effect.h>
#include <d3dCompiler.h>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#define SAFE_RELEASE(x) if( x ) { (x)->Release(); (x) = NULL; }
#define SAFE_DELETE(x) if( x ) { delete(x); (x) = NULL; }
#define SAFE_DELETE_ARRAY(x) if( x ) { delete[](x); (x) = NULL; }
#define PI (3.14159265358979323846f)
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")
#pragma comment (lib,"dxerr.lib")
#ifdef _DEBUG
#pragma comment(lib, "d3dx11d.lib")
#pragma comment(lib, "Effects11D.lib")
#pragma comment(lib, "d3dx10d.lib")
#else
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "Effects11.lib")
#pragma comment(lib, "d3dx10.lib")
#endif
#endif

539
OysterGraphics/Engine.cpp Normal file
View File

@ -0,0 +1,539 @@
#include "Engine.h"
bool CreateDepthStencil(bool MSAA_Quality);
bool CreateRenderTarget();
void SetViewPort();
class oysterPrivates
{
public:
bool instance,swapChained;
ID3D11DepthStencilView* depth;
ID3D11RenderTargetView *rtv;
ID3D11UnorderedAccessView *uav;
ID3D11ShaderResourceView* depthTexture;
DXGI_SAMPLE_DESC sampleDesc;
D3D11_VIEWPORT viewPort;
oysterPrivates():instance(false),swapChained(false),depth(NULL),rtv(NULL), depthTexture(NULL){};
class State
{
public:
int NrOfSamples;
int SampleSpread;
int NrOfPointlights;
}States;
}instance;
Oyster::Engine::Engine()
{
}
Oyster::Engine::~Engine()
{
}
//Init
bool Oyster::Engine::Init::IsInstanced()
{
return instance.instance;
}
bool Oyster::Engine::Init::Instance(bool SingleThreaded,bool Reference,bool ForceDX11)
{
if(!instance.instance)
if(Oyster::Core::Init(SingleThreaded,Reference,ForceDX11))
instance.instance=true;
return instance.instance;
}
bool Oyster::Engine::Init::HasSwapChain()
{
return instance.swapChained;
}
bool Oyster::Engine::Init::CreateSwapChain(HWND Window,int NrofBuffers,bool MSAA_Quality,bool Fullscreen)
{
if(Window==0)
{
if(Oyster::Window::Handle==0)
return false;
else
Window = Oyster::Window::Handle;
}
if(!instance.swapChained)
{
if(Oyster::Core::CreateSwapChain(Window,NrofBuffers,MSAA_Quality,Fullscreen))
instance.swapChained=true;
}
return instance.swapChained;
}
bool Oyster::Engine::Init::InitializeWindow(const LPCSTR appName, const LPCSTR className,const HINSTANCE &hInstance, const int &nCmdShow, WNDPROC wProc, bool handleLoop )
{
return Oyster::Window::init(appName,className,hInstance,nCmdShow,wProc,handleLoop);
}
bool Oyster::Engine::Init::FullInit(const Setup& setup)
{
if(!Oyster::Engine::Init::Instance(setup.Common.SingleThreaded,setup.Common.Reference,setup.Common.ForceDX11))
return false;
if(setup.Window.InitWindow)
if(!Oyster::Engine::Init::InitializeWindow(setup.Window.appname,setup.Window.classname,setup.Window.hinstance,setup.Window.nCmdShow,setup.Window.wProc, true))
return false;
if(!Oyster::Engine::Init::CreateSwapChain(NULL,setup.Common.NrOfBuffers,setup.Common.MSAA_Quality,setup.Common.Fullscreen))
return false;
if(!Oyster::Shader::InitShaders())
return false;
if(setup.Common.GenerateDepthStencil)
if(!CreateDepthStencil(setup.Common.MSAA_Quality))
return false;
if(!CreateRenderTarget())
return false;
if(!Oyster::Render::Textbox::Init())
return false;
SetViewPort();
if(setup.Common.BindDefault)
Oyster::Engine::PrepareForRendering::BindRenderTargets(&instance.rtv,1,instance.depth);
instance.States.NrOfSamples = 14;
instance.States.SampleSpread = 4;
instance.States.NrOfPointlights = 1024;
Oyster::Resources::Buffers::Init();
Oyster::Resources::ShaderEffects::Init();
Oyster::Resources::PipeLineResourses::Init();
return true;
}
Oyster::Buffer* Oyster::Engine::Init::Buffers::CreateBuffer(const Oyster::Buffer::BUFFER_INIT_DESC desc)
{
Oyster::Buffer *buffy = new Oyster::Buffer();
buffy->Init(desc);
return buffy;
}
//PrepareForRendering
void Oyster::Engine::PrepareForRendering::BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets,ID3D11DepthStencilView* depth)
{
Oyster::Core::DeviceContext->OMSetRenderTargets(NrOfTargets,RenderTargets,depth);
}
void Oyster::Engine::PrepareForRendering::BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets)
{
Oyster::Core::DeviceContext->OMSetRenderTargets(NrOfTargets,RenderTargets,instance.depth);
}
void Oyster::Engine::PrepareForRendering::BindBackBufferAsUAV()
{
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,1,&instance.uav,0);
}
void Oyster::Engine::PrepareForRendering::BindUAV(ID3D11UnorderedAccessView** uav, int NrOfUavs)
{
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,NrOfUavs,uav,0);
}
void Oyster::Engine::PrepareForRendering::ClearBackBuffer(Math::Float4 color)
{
Oyster::Core::DeviceContext->ClearRenderTargetView(instance.rtv,(float*)color);
Oyster::Core::DeviceContext->ClearDepthStencilView(instance.depth,1,1,0);
}
void Oyster::Engine::PrepareForRendering::BindBackBuffer(ID3D11DepthStencilView* depth)
{
Oyster::Core::DeviceContext->OMSetRenderTargets(1,&instance.rtv,depth);
}
void Oyster::Engine::PrepareForRendering::BindBackBuffer()
{
Oyster::Core::DeviceContext->OMSetRenderTargets(1,&instance.rtv,instance.depth);
}
void Oyster::Engine::PrepareForRendering::Begin2DRender()
{
Oyster::Resources::Buffers::V2DSprites.Apply();
Oyster::Resources::Buffers::CBufferGs.Apply();
Shader::SetShaderEffect(Oyster::Resources::ShaderEffects::BasicSprite);
}
void Oyster::Engine::PrepareForRendering::Begin2DTextRender()
{
Oyster::Render::Textbox::TextBuffer.Apply();
Oyster::Resources::Buffers::CBufferGs.Apply();
Oyster::Shader::SetShaderEffect(Oyster::Resources::ShaderEffects::Text2DEffect);
}
//Render
void Oyster::Engine::Render::PresentScene()
{
Core::SwapChain->Present(0,0);
}
void Oyster::Engine::Render::Geometry(const Oyster::Render::Model* models,int count,Oyster::Buffer* cBufferEveryObject, int slot)
{
if(cBufferEveryObject)
cBufferEveryObject->Apply(slot);
for(int i=0;i<count;++i)
{
if(models[i].Visible)
{
if(cBufferEveryObject)
{
void* data = cBufferEveryObject->Map();
memcpy(data,&(models[i].World->getTranspose()),64);
cBufferEveryObject->Unmap();
}
Oyster::Core::DeviceContext->PSSetShaderResources(0,models[i].info->Material.size(),&(models[i].info->Material[0]));
models[i].info->Vertices.Apply();
if(models[i].info->Indexed)
{
models[i].info->Indecies.Apply();
Oyster::Core::DeviceContext->DrawIndexed(models[i].info->VertexCount,0,0);
}
else
Oyster::Core::DeviceContext->Draw(models[i].info->VertexCount,0);
}
}
}
void Oyster::Engine::Render::Text(std::string text, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos)
{
Pos.x -= Oyster::Window::Size.left/2;
Pos.x += size.x;
Pos.y -= Oyster::Window::Size.bottom/2;
Pos.y += size.y;
Matrix m;
Math::identityMatrix(m);
float width = (1.0f/(Window::Size.left/2.0f));
float height = (1.0f/(Window::Size.bottom/2.0f));
m.m41=Pos.x * width;
m.m42=-Pos.y * height;
m.m43=Pos.z;
m.m11=width*size.x;
m.m22=height*size.y;
void* dest = Resources::Buffers::CBufferGs.Map();
memcpy(dest,&m.getTranspose(),64);
Resources::Buffers::CBufferGs.Unmap();
Oyster::Render::Textbox::Update(text, size.x);
Oyster::Engine::PrepareForRendering::Begin2DTextRender();
Oyster::Core::DeviceContext->PSSetShaderResources(0,1,&(Oyster::Render::Textbox::Texture));
//Should be able to be outside of the for loop. Keeping it here for now though.
Oyster::Core::DeviceContext->Draw(Oyster::Render::Textbox::NumLetters, 0);
}
void Oyster::Engine::Render::ScreenQuad(ID3D11ShaderResourceView* srv, float ZPos)
{
Oyster::Core::DeviceContext->PSSetShaderResources(0,1,&srv);
Matrix m;
Math::identityMatrix(m);
m.m43=ZPos;
void* dest = Resources::Buffers::CBufferGs.Map();
memcpy(dest,&m.getTranspose(),64);
Resources::Buffers::CBufferGs.Unmap();
Oyster::Core::DeviceContext->Draw(1,0);
}
void Oyster::Engine::Render::Sprite(ID3D11ShaderResourceView* srv, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos)
{
Oyster::Core::DeviceContext->PSSetShaderResources(0,1,&srv);
Pos.x -= Oyster::Window::Size.left/2;
Pos.x += size.x/2;
Pos.y -= Oyster::Window::Size.bottom/2;
Pos.y += size.y/2;
Matrix m;
Math::identityMatrix(m);
float width = (1.0f/(Window::Size.left/2.0f));
float height = (1.0f/(Window::Size.bottom/2.0f));
m.m41=Pos.x * width;
m.m42=-Pos.y * height;
m.m43=Pos.z;
m.m11=width*size.x/2;
m.m22=height*size.y/2;
void* dest = Resources::Buffers::CBufferGs.Map();
memcpy(dest,&m.getTranspose(),64);
Resources::Buffers::CBufferGs.Unmap();
Oyster::Core::DeviceContext->Draw(1,0);
}
//Misc
bool CreateDepthStencil(bool MSAA_Quality)
{
D3D11_TEXTURE2D_DESC desc;
desc.MipLevels=1;
desc.ArraySize=1;
desc.Format = DXGI_FORMAT_D32_FLOAT;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags=0;
desc.MiscFlags=0;
desc.Height = Oyster::Window::Size.bottom;
desc.Width = Oyster::Window::Size.left;
//Check and Set multiSampling
if(MSAA_Quality)
{
if(FAILED(Oyster::Core::Device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&desc.SampleDesc.Quality)))
{
//Log<< "Failed to check multisample quality levels (MSAAQuality).\n";
return false;
}
desc.SampleDesc.Count=4;
--desc.SampleDesc.Quality;
//Log << "Supported multisample quality levels (MSAAQuality): " << desc.SampleDesc.Quality+1 << "x\n";
}
else
{
desc.SampleDesc.Count=1;
desc.SampleDesc.Quality=0;
}
ID3D11Texture2D* depthstencil;
if(FAILED(Oyster::Core::Device->CreateTexture2D(&desc,0,&depthstencil)))
return false;
if(FAILED(Oyster::Core::Device->CreateDepthStencilView(depthstencil,0,&instance.depth)))
{
depthstencil->Release();
return false;
}
depthstencil->Release();
return true;
}
bool CreateRenderTarget()
{
D3D11_UNORDERED_ACCESS_VIEW_DESC descView;
ZeroMemory( &descView, sizeof(descView) );
descView.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
descView.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
descView.Texture2D.MipSlice=0;
ID3D11Texture2D* backBuffer;
if(FAILED(Oyster::Core::SwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),reinterpret_cast<void**>(&backBuffer))))
return false;
if(FAILED(Oyster::Core::Device->CreateRenderTargetView(backBuffer,0,&instance.rtv)))
{
backBuffer->Release();
return false;
}
if(FAILED(Oyster::Core::Device->CreateUnorderedAccessView(backBuffer,0,&instance.uav)))
{
backBuffer->Release();
return false;
}
backBuffer->Release();
return true;
}
void SetViewPort()
{
instance.viewPort.TopLeftX = 0.0f;
instance.viewPort.TopLeftY = 0.0f;
instance.viewPort.Width = (float)Oyster::Window::Size.left;
instance.viewPort.Height = (float)Oyster::Window::Size.bottom;
instance.viewPort.MinDepth = 0.0f;
instance.viewPort.MaxDepth = 1.0f;
Oyster::Core::DeviceContext->RSSetViewports(1,&instance.viewPort);
}
void Blur(int target)
{
//TODO: proper size calculation
//bind input
Oyster::Core::DeviceContext->CSSetShaderResources(0,1,&Oyster::Resources::PipeLineResourses::LightOut[target]);
Oyster::Engine::PrepareForRendering::BindUAV(&Oyster::Resources::PipeLineResourses::TempUav,1);
//dispatch blurr horizontal
Oyster::Shader::Set::SetCompute(Oyster::Shader::Get::GetCompute("BlurHorizontal"));
Oyster::Core::DeviceContext->Dispatch(7,Oyster::Window::Size.bottom,1);
//clean Pipeline
Oyster::Core::DeviceContext->CSSetShaderResources(0,16,&Oyster::Resources::PipeLineResourses::SrvNulls[0]);
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,8,&Oyster::Resources::PipeLineResourses::uavNULL[0],0);
//bind input
Oyster::Core::DeviceContext->CSSetShaderResources(0,1,&Oyster::Resources::PipeLineResourses::TempSrv);
Oyster::Engine::PrepareForRendering::BindUAV(&Oyster::Resources::PipeLineResourses::LightTarget[target],1);
//dispatch blurr vertical
Oyster::Shader::Set::SetCompute(Oyster::Shader::Get::GetCompute("BlurVertical"));
Oyster::Core::DeviceContext->Dispatch(Oyster::Window::Size.left,5,1);
//clean Pipeline
Oyster::Core::DeviceContext->CSSetShaderResources(0,16,&Oyster::Resources::PipeLineResourses::SrvNulls[0]);
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews(0,8,&Oyster::Resources::PipeLineResourses::uavNULL[0],0);
}
//Pipeline Render
void Oyster::Engine::Pipeline::Deffered_Lightning::NewFrame(const Float4& col, const Matrix& View, const Matrix& Projection)
{
//diffuse
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[0], col);
//Specular
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[1], col);
//Glow
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[2], col);
//Pos
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[3], col);
//Normal
Oyster::Core::DeviceContext->ClearRenderTargetView( Oyster::Resources::PipeLineResourses::GeometryTarget[4], col);
Oyster::Engine::PrepareForRendering::ClearBackBuffer(col);
//Upload Camera to Resources
Matrix P = Oyster::Math::Float4x4(Projection);
Matrix V = Oyster::Math::Float4x4(View);
Matrix VP = V*P;
Oyster::Resources::PipeLineResourses::LightData.projectionMatrix = P.getTranspose();
Oyster::Resources::PipeLineResourses::LightData.viewMatrix = V;
Oyster::Collision::Frustrum( VP ).split(Oyster::Resources::PipeLineResourses::SubFrustrums, Oyster::Resources::PipeLineResourses::FrustrumDimensions.x, Oyster::Resources::PipeLineResourses::FrustrumDimensions.y, Oyster::Resources::PipeLineResourses::FrustrumDimensions.z );
void* dest = Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[0]->Map();
memcpy(dest,&VP.getTranspose(),64);
Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[0]->Unmap();
dest= Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[1]->Map();
memcpy(dest,&V.getTranspose(),64);
Oyster::Resources::ShaderEffects::ModelEffect.CBuffers.Vertex[1]->Unmap();
dest = Oyster::Resources::PipeLineResourses::Resources[0]->Map();
unsigned int bytes=0;
for(int i=0;i<Oyster::Resources::PipeLineResourses::FrustrumSize;++i)
{
Oyster::Resources::PipeLineResourses::SubFrustrums[i].writeToByte( (unsigned char*)dest,bytes);
}
Oyster::Resources::PipeLineResourses::Resources[0]->Unmap();
dest = Oyster::Resources::Buffers::CBufferPipelineCs.Map();
memcpy(dest, &Oyster::Resources::PipeLineResourses::LightData, sizeof( Oyster::Resources::BufferDefinitions::LightStructureBuffer ) );
Oyster::Resources::Buffers::CBufferPipelineCs.Unmap();
}
void Oyster::Engine::Pipeline::Deffered_Lightning::BeginRenderGeometry()
{
Oyster::Engine::PrepareForRendering::BindRenderTargets( Oyster::Resources::PipeLineResourses::GeometryTarget, 5 );
Oyster::Shader::SetShaderEffect( Oyster::Resources::ShaderEffects::ModelEffect );
}
void Oyster::Engine::Pipeline::Deffered_Lightning::RenderGeometry(const Oyster::Render::Model* models,int count)
{
//TODO: Add sorting to minimiza state changes
Render::Geometry( models, count, &Oyster::Resources::Buffers::CbufferVS, 2 );
}
void Oyster::Engine::Pipeline::Deffered_Lightning::EndRenderGeometry()
{
//TODO: Actualy Render data from previous pass
Oyster::Engine::PrepareForRendering::BindRenderTargets( Oyster::Resources::PipeLineResourses::RtvNulls, 8, NULL );
Oyster::Core::DeviceContext->PSSetShaderResources(0, 16, Oyster::Resources::PipeLineResourses::SrvNulls);
}
void Oyster::Engine::Pipeline::Deffered_Lightning::InputPointLights(Oyster::Resources::BufferDefinitions::PointLightDescription *p, int nr)
{
void* dest = Oyster::Resources::PipeLineResourses::Resources[1]->Map();
memcpy(dest, p, sizeof(Oyster::Resources::BufferDefinitions::PointLightDescription) * nr );
Oyster::Resources::PipeLineResourses::Resources[1]->Unmap();
}
void Oyster::Engine::Pipeline::Deffered_Lightning::RenderLightning()
{
Oyster::Engine::PrepareForRendering::BindUAV( Oyster::Resources::PipeLineResourses::LightTarget, 4 );
Oyster::Core::DeviceContext->CSSetShaderResources(0,5, Oyster::Resources::PipeLineResourses::GeometryOut);
Oyster::Resources::Buffers::CBufferPipelineCs.Apply();
Oyster::Core::DeviceContext->CSSetShaderResources( 6, 4, Oyster::Resources::PipeLineResourses::ComputeResources );
Oyster::Shader::Set::SetCompute( Oyster::Shader::Get::GetCompute("Pass0") );
Oyster::Core::DeviceContext->Dispatch( 49, 36, 1 );
//clean Pipeline
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 16, Oyster::Resources::PipeLineResourses::SrvNulls );
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews( 0, 8, Oyster::Resources::PipeLineResourses::uavNULL, 0 );
//Blurr
//Blur( 2 );
//Blur( 3 );
//clean Pipeline
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 16, Oyster::Resources::PipeLineResourses::SrvNulls );
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews( 0, 8, Oyster::Resources::PipeLineResourses::uavNULL, 0 );
//prepare and render final pass
Oyster::Engine::PrepareForRendering::BindBackBufferAsUAV();
Oyster::Shader::Set::SetCompute( Oyster::Shader::Get::GetCompute("Pass1") );
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 4, Oyster::Resources::PipeLineResourses::LightOut );
Oyster::Core::DeviceContext->Dispatch( 49, 36, 1 );
//clean Pipeline
Oyster::Core::DeviceContext->CSSetShaderResources( 0, 16, Oyster::Resources::PipeLineResourses::SrvNulls );
Oyster::Core::DeviceContext->CSSetUnorderedAccessViews( 0, 8, Oyster::Resources::PipeLineResourses::uavNULL, 0 );
}
//States
int Oyster::Engine::States::GetNrOfSSAOSamples()
{
return instance.States.NrOfSamples;
}
void Oyster::Engine::States::SetNrOfSSAOSamples(int nr)
{
instance.States.NrOfSamples = nr;
}
int Oyster::Engine::States::GetSSAOSampleSpread()
{
return instance.States.SampleSpread;
}
void Oyster::Engine::States::SetSSAOSampleSpread(int spread)
{
instance.States.SampleSpread = spread;
}
int Oyster::Engine::States::GetMaxPointlights()
{
return instance.States.NrOfPointlights;
}
void Oyster::Engine::States::SetMaxPointlights(int nr)
{
instance.States.NrOfPointlights = nr;
}

177
OysterGraphics/Engine.h Normal file
View File

@ -0,0 +1,177 @@
#pragma once
#ifndef Engine_h
#define Engine_h
#define NOMINMAX // Because I hate Microsoft now. ~Angry Dan. http://lolengine.net/blog/2011/3/4/fuck-you-microsoft-near-far-macros
#include "EngineIncludes.h"
namespace Oyster
{
class Engine
{
private:
Engine();
~Engine();
public:
class Init
{
public:
struct Setup
{
struct
{
bool InitWindow;
LPCSTR appname;
LPCSTR classname;
HINSTANCE hinstance;
int nCmdShow;
WNDPROC wProc;
bool ManageWindow;
}Window;
struct
{
int NrOfBuffers;
bool MSAA_Quality;
bool Fullscreen;
bool SingleThreaded;
bool Reference;
bool ForceDX11;
bool GenerateDepthStencil;
bool BindDefault;
}Common;
//all but Window params have Default Values
Setup()
{
Common.NrOfBuffers=1;
Common.MSAA_Quality = false;
Common.Fullscreen = true;
Common.SingleThreaded = true;
Common.Reference = false;
Common.ForceDX11 = false;
Common.GenerateDepthStencil = true;
Common.BindDefault = true;
}
};
static bool IsInstanced();
//Creates Device and DeviceContext, if not Initialized
static bool Instance(bool SingleThreaded=true,bool Reference=false,bool ForceDX11=false);
static bool HasSwapChain();
//Creates Swapchain, if not Aready Created
static bool CreateSwapChain(HWND Window, int NrofBuffers=1,bool MSAA_Quality=false,bool Fullscreen=true);
//CreateWindow, if Not Already Created
static bool InitializeWindow(const LPCSTR appName, const LPCSTR className,const HINSTANCE &hInstance, const int &nCmdShow, WNDPROC wProc, bool HandleLoop = false );
//Performs a full initialization of a rendering pipeline, including a Window
static bool FullInit(const Setup& setup);
struct Buffers
{
static Buffer* CreateBuffer(const Buffer::BUFFER_INIT_DESC BufferDesc);
};
private:
Init();
~Init();
};
class States
{
public:
//SSAO Quality
static void SetNrOfSSAOSamples(int);
static int GetNrOfSSAOSamples();
//SSAO Frequency
static void SetSSAOSampleSpread(int);
static int GetSSAOSampleSpread();
//PointLights
static void SetMaxPointlights(int);
static int GetMaxPointlights();
private:
States();
~States();
};
class Render
{
public:
/// Render a number of models, setting the Per model data to the included cBuffer
/// specify NULL if no such data exists
static void Geometry(const Oyster::Render::Model* models,int count,Oyster::Buffer* cBufferEveryObject, int slot);
static void Text(std::string text, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos);
//static void TextBox(const Oyster::Render::
//ensure that a compatible 2D shadereffect is applied
static void ScreenQuad(ID3D11ShaderResourceView* srv, float ZPos=1);
//ensure that a compatible 2D shadereffect is applied and that pos.z is between 0 and 1
static void Sprite(ID3D11ShaderResourceView* srv, Oyster::Math::Float2 size, Oyster::Math::Float3 Pos);
static void PresentScene();
private:
Render();
~Render();
};
class PrepareForRendering
{
public:
//Binds several rendertargets and a depthstencil
static void BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets,ID3D11DepthStencilView* depth);
//Binds several Rendertargest and a default depthstencil
static void BindRenderTargets(ID3D11RenderTargetView** RenderTargets,int NrOfTargets);
//Binds the backbuffer and a depthstencil
static void BindBackBuffer(ID3D11DepthStencilView* depth);
//Binds the backbuffer and a default depthstencil
static void BindBackBuffer();
//Binds the backbuffer to the compute shader
static void BindBackBufferAsUAV();
//binds several UAV to the computeshader
static void BindUAV(ID3D11UnorderedAccessView** uav, int NrOfUavs);
//Clears the backbuffer and default depthstencil
static void ClearBackBuffer(Math::Float4 color);
static void Begin2DRender();
static void Begin2DTextRender();
};
class Pipeline
{
public:
class Deffered_Lightning
{
public:
//Basic Setup
static void NewFrame(const Float4& Color, const Matrix& View, const Matrix& Projection);
//Geometry Pass
static void BeginRenderGeometry();
static void RenderGeometry(const Oyster::Render::Model* models,int count);
static void EndRenderGeometry();
//Lightning Pass
static void InputPointLights(Oyster::Resources::BufferDefinitions::PointLightDescription *p, int NrOfPointlights );
static void RenderLightning();
};
};
};
};
#endif

View File

@ -0,0 +1,38 @@
//Oyster
// Render
#include "Render\Model.h"
#include "Render\Camera.h"
#include "Render\TextBox.h"
// Core
#include "Core\Core.h"
#include "Core\Buffer.h"
// Shader
#include "Shader\Shader.h"
// Math
#include "Math\OysterMath.h"
// FileLoader
#include "FileLoader\ObjReader.h"
// Windows
#include "Window\Window.h"
// Input
#include "Input\InputController.h"
// Collision
#include "Collision\Collision.h"
// Game Definitions
#include "Game\OysterGame.h"
// Resources
#include "Resourses\ShaderEffects.h"
#include "Resourses\Buffers.h"
#include "Resourses\PipelineResources.h"
#include "Resourses\GraphicsDefinitions.h"
#include "Resourses\Manager.h"

View File

@ -0,0 +1,268 @@
#include "ObjReader.h"
#include "Utilities.h"
#include "..\Core\Core.h"
#include <fstream>
#include <map>
using namespace std;
using namespace Oyster::FileLoaders;
using namespace Oyster;
using namespace Oyster::Math;
ObjReader *ObjReader::LoadFile(std::string fileName, Oyster::Math::Float4x4 transform)
{
static std::map<std::string, ObjReader *> cache;
ObjReader *reader = NULL;
if (cache.count(fileName))
{
reader = cache[fileName];
}
else
{
reader = new ObjReader();
reader->ParseFile(fileName, transform);
cache[fileName] = reader;
}
return reader;
}
ObjReader::ObjReader(void)
{
}
ObjReader::~ObjReader(void)
{
}
void ObjReader::ParseFile(std::string fileName, Float4x4 transform)
{
ifstream input;
input.open(fileName.c_str());
if(!input.is_open())
{
return;
}
string path;
Utility::String::extractDirPath(path,fileName,'\\');
std::vector<Vertex> VertexList;
std::vector<Float3> vList;
std::vector<Float3> nList;
std::vector<Float2> uvList;
Vertex vertex1, vertex2, vertex3;
Float3 face[3];
Float3 position, normal;
Float2 uv;
string s;
while(!input.eof())
{
getline(input,s);
int offset = (int)s.find(' ');
if(offset!=-1)
{
string c = s.substr(0,offset);
if(c=="v")
{
position = readVertex(offset,s);
vList.push_back(position);
}
else if(c=="vt")
{
uv = readUV(offset,s);
uvList.push_back(uv);
}
else if(c=="vn")
{
normal = readNormal(offset,s);
nList.push_back(normal);
}
else if(c=="f")
{
readFace(offset, s, face);
vertex1.Position = vList[(int)face[0].x];
vertex1.UV = uvList[(int)face[0].y];
vertex1.Normal = nList[(int)face[0].z];
vertex2.Position = vList[(int)face[1].x];
vertex2.UV = uvList[(int)face[1].y];
vertex2.Normal = nList[(int)face[1].z];
vertex3.Position = vList[(int)face[2].x];
vertex3.UV = uvList[(int)face[2].y];
vertex3.Normal = nList[(int)face[2].z];
VertexList.push_back(vertex1);
VertexList.push_back(vertex3);
VertexList.push_back(vertex2);
}
else if(c=="mtllib")
{
this->materials = GetMaterials(path+s.substr(offset+1));
}
}
}
input.close();
this->numVertices = VertexList.size();
this->vertices = new Vertex[this->numVertices];
for(size_t i=0;i<this->numVertices;++i)
{
vertices[i].Position=Math::transformVector(Math::Float4(VertexList[i].Position,1),transform);
vertices[i].Normal=Math::transformVector(Math::Float4(VertexList[i].Normal,0),transform);
vertices[i].UV = VertexList[i].UV;
}
}
void ObjReader::GetVertexData(Vertex **vertex,int &numVertex, std::map<std::string, ID3D11ShaderResourceView *> &Textures)
{
numVertex=(int)this->numVertices;
(*vertex)=this->vertices;
Textures = this->materials;
}
Float3 ObjReader::extract(std::string d)
{
Float3 data;
int offset=(int)d.find('/');
data.x=(float)atoi(d.substr(1,offset).c_str())-1;
int newOffset = (int)d.find('/',offset+1);
string d2=d.substr(offset+1,newOffset-offset-1);
data.y=(float)atoi(d2.c_str())-1;
offset=newOffset;
newOffset = (int)d.find('/',offset+1);
string d3=d.substr(offset+1,newOffset-offset-1);
data.z=(float)atoi(d3.c_str())-1;
return data;
}
Float3 ObjReader::readVertex(int offset,string s)
{
int newOffset = (int)s.find(' ',offset+1);
Float3 vertex;
string d = s.substr(offset,newOffset-offset);
vertex.x = (float)atof(d.c_str());
offset=newOffset;
newOffset = (int)s.find(' ',offset+1);
vertex.y = (float)atof(s.substr(offset,newOffset-offset).c_str());
offset=newOffset;
newOffset = (int)s.find(' ',offset+1);
vertex.z = (float)-atof(s.substr(offset,newOffset-offset).c_str());
return vertex;
}
Float2 ObjReader::readUV(int offset,string s)
{
int newOffset = (int)s.find(' ',offset+1);
Float2 uv;
string d = s.substr(offset,newOffset-offset);
uv.x =(float)atof(d.c_str());
offset=newOffset;
newOffset = (int)s.find(' ',offset+1);
d = s.substr(offset,newOffset-offset);
uv.y =1- (float)atof(d.c_str());
offset=newOffset;
return uv;
}
Float3 ObjReader::readNormal(int offset,string s)
{
int newOffset = (int)s.find(' ',offset+1);
Float3 vertex;
string d = s.substr(offset,newOffset-offset);
vertex.x = (float)atof(d.c_str());
offset=newOffset;
newOffset = (int)s.find(' ',offset+1);
vertex.y = (float)atof(s.substr(offset,newOffset-offset).c_str());
offset=newOffset;
newOffset = (int)s.find(' ',offset+1);
vertex.z = (float)-atof(s.substr(offset,newOffset-offset).c_str());
return vertex;
}
void ObjReader::readFace(int offset,string s, Oyster::Math::Float3 face[3])
{
int newOffset = (int)s.find(' ',offset+1);
string point1 = s.substr(offset,newOffset-offset);
offset = newOffset;
newOffset = (int)s.find(' ',offset+1);
string point2 = s.substr(offset,newOffset-offset);
offset = newOffset;
newOffset = (int)s.find(' ',offset+1);
string point3 = s.substr(offset,newOffset-offset);
face[0] = extract(point1);
face[1] = extract(point2);
face[2] = extract(point3);
}
std::map<std::string, ID3D11ShaderResourceView *> ObjReader::GetMaterials(std::string fileName)
{
ifstream input;
input.open(fileName.c_str());
std::map<std::string, ID3D11ShaderResourceView *> materials;
ID3D11ShaderResourceView *srv;
string texture;
string s;
string path;
Utility::String::extractDirPath(path,fileName,'\\');
if(!input.is_open())
return materials;
while(!input.eof())
{
getline(input,s);
int offset = (int)s.find(' ');
if(offset!=-1)
{
string c = s.substr(0,offset);
if(c=="map_Kd")
{
texture = path+s.substr(offset+1);
D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL);
materials["Diffuse"] = srv;
}
if(c=="map_G")
{
texture = path+s.substr(offset+1);
D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL);
materials["Glow"] = srv;
}
if(c=="map_Ks")
{
texture = path+s.substr(offset+1);
D3DX11CreateShaderResourceViewFromFile(Oyster::Core::Device,texture.c_str(), NULL, NULL, &srv, NULL);
materials["Specular"] = srv;
}
}
}
input.close();
return materials;
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "..\Core\CoreIncludes.h"
#include "..\Math\OysterMath.h"
namespace Oyster
{
namespace FileLoaders
{
class ObjReader
{
public:
struct Vertex
{
Oyster::Math::Float3 Position;
Oyster::Math::Float3 Normal;
Oyster::Math::Float2 UV;
};
static ObjReader *LoadFile(std::string fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity);
ObjReader(void);
~ObjReader(void);
void GetVertexData(Vertex **vertex,int &numVertex, std::map<std::string, ID3D11ShaderResourceView *> &textures);
private:
Vertex *vertices;
size_t numVertices;
std::map<std::string, ID3D11ShaderResourceView *> materials;
void ParseFile(std::string fileName, Oyster::Math::Float4x4 transform = Oyster::Math::Float4x4::identity);
Oyster::Math::Float3 extract(std::string d);
Oyster::Math::Float3 readVertex(int offset,std::string s);
Oyster::Math::Float2 readUV(int offset,std::string s);
Oyster::Math::Float3 readNormal(int offset,std::string s);
void readFace(int offset,std::string s, Oyster::Math::Float3 face[3]);
std::map<std::string, ID3D11ShaderResourceView *> GetMaterials(std::string fileName);
};
}
}

View File

@ -0,0 +1,157 @@
#include "Camera.h"
//Hack: temp include, calc proj matrix properly later
#include "..\Core\CoreIncludes.h"
using namespace Oyster;
using namespace Render;
using namespace Oyster::Math;
Camera::Camera(void)
{
}
Camera::~Camera(void)
{
}
Math::Float3 Camera::GetPosition() {return pos;}
void Camera::SetPosition(Math::Float3 p){ pos=p;}
//axis
Math::Float3 Camera::GetRight() {return right;}
Math::Float3 Camera::GetUp() {return up;}
Math::Float3 Camera::GetLook() {return look;}
//frustrum
float Camera::GetNearZ(){return nearZ;}
float Camera::GetFarZ(){return farZ;}
float Camera::GetAspect(){return aspect;}
float Camera::GetFovY(){return fovY;}
float Camera::GetFovX(){return fovX;}
//set frustrum
void Camera::SetLens(float fovY, float aspect, float zn, float zf)
{
this->fovY=fovY;
this->aspect=aspect;
nearZ=zn;
farZ=zf;
D3DXMATRIX P;
D3DXMatrixPerspectiveFovLH(&P,fovY,aspect,zn,zf);
mProj = Math::Float4x4(P);
}
//normal LookAt
void Camera::LookAt(Math::Float3 pos, Math::Float3 target, Math::Float3 worldUp)
{
look=target;
up=worldUp;
this->pos=pos;
right = up.cross(look);
}
//Get Matrices
Matrix Camera::View(){return mView;}
Matrix Camera::Proj(){return mProj;}
Matrix Camera::ViewProj()
{
return (mView * mProj).transpose(); // edited by Dan 04-19
}
//Move Camera
//FIX: Multiply Add not working
//FIX: Single Float Duplicate Creation
void Camera::Strafe(float d)
{
Math::Float3 s= Math::Float3(d,d,d);
pos= (Math::operator*(s,right)) + pos;
}
void Camera::Walk(float d)
{
Math::Float3 s= Math::Float3(d,d,d);
pos= (Math::operator*(s,look)) + pos;
}
void Camera::Fly(float d)
{
Math::Float3 s= Math::Float3(d,d,d);
pos= (Math::operator*(s,up)) + pos;
}
//Rotate Camera
//FIX: Float3 * float4x4
void Camera::Pitch(float angle)
{
Matrix m;
Math::rotationMatrix(m,angle,right);
m = m.getAdjoint().getInverse();
up = (Math::Float4(up,0) * m).xyz;
look = (Math::Float4(look,0) * m).xyz;
}
void Camera::Yaw(float angle)
{
Matrix m;
Math::rotationMatrix(m,angle,up);
m = m.getAdjoint().getInverse();
right = (Math::Float4(right,0) * m).xyz;
look = (Math::Float4(look,0) * m).xyz;
}
void Camera::Roll(float angle)
{
Matrix m;
Math::rotationMatrix(m, angle,look);
m = m.getAdjoint().getInverse();
up = (Math::Float4(up,0) * m).xyz;
right = (Math::Float4(right,0) * m).xyz;
}
void Camera::RotateY(float angle)
{
Matrix m;
Math::rotationMatrix_AxisY(m, angle);
m = m.getAdjoint().getInverse();
up = (Math::Float4(up,0) * m).xyz;
look = (Math::Float4(look,0) * m).xyz;
right = (Math::Float4(right,0) * m).xyz;
}
void Camera::UpdateViewMatrix()
{
look.normalize();
up = look.cross(right);
up.normalize();
right = up.cross(look);
float x = -pos.dot(right);
float y = -pos.dot(up);
float z = -pos.dot(look);
mView.m[0][0] = right.x;
mView.m[1][0] = right.y;
mView.m[2][0] = right.z;
mView.m[3][0] = x;
mView.m[0][1] = up.x;
mView.m[1][1] = up.y;
mView.m[2][1] = up.z;
mView.m[3][1] = y;
mView.m[0][2] = look.x;
mView.m[1][2] = look.y;
mView.m[2][2] = look.z;
mView.m[3][2] = z;
mView.m[0][3] = 0.0f;
mView.m[1][3] = 0.0f;
mView.m[2][3] = 0.0f;
mView.m[3][3] = 1.0f;
}

View File

@ -0,0 +1,61 @@
#pragma once
#include "..\Math\OysterMath.h"
namespace Oyster
{
namespace Render
{
class Camera
{
public:
Camera(void);
~Camera(void);
//position
Math::Float3 GetPosition();
void SetPosition(Math::Float3);
//axis
Math::Float3 GetRight();
Math::Float3 GetUp();
Math::Float3 GetLook();
//frustrum
float GetNearZ();
float GetFarZ();
float GetAspect();
float GetFovY();
float GetFovX();
//set frustrum
void SetLens(float fovY, float aspect, float zn, float zf);
//normal LookAt
void LookAt(Math::Float3 pos, Math::Float3 target, Math::Float3 worldUp);
//Get Matrices
Math::Matrix View();
Math::Matrix Proj();
Math::Matrix ViewProj();
//Move Camera
void Strafe(float d);
void Walk(float d);
void Fly(float d);
//Rotate Camera
void Pitch(float angle);
void Yaw(float angle);
void Roll(float angle);
void RotateY(float angle);
void UpdateViewMatrix();
private:
Math::Vector3 pos, right, up, look;
float nearZ,farZ,aspect,fovX,fovY;
Math::Matrix mView, mProj;
};
}
}

View File

@ -0,0 +1,8 @@
#pragma once
#include "Engine\Math\OysterMath.h"
struct DirectionalLight
{
Oyster::Math::Float4 Irradiance;
Oyster::Math::Float4 Direction;
};

View File

View File

@ -0,0 +1,32 @@
#pragma once
#ifndef Mesh_h
#define Mesh_h
//#include "../Engine.h"
//#include "..\Core\CoreIncludes.h"
//#include "..\Core\Buffer.h"
#include "OysterMath.h"
//#include "ICollideable.h"
#include "ModelInfo.h"
using namespace Oyster::Math;
namespace Oyster
{
namespace Render
{
struct Model
{
ModelInfo* info;
Float4x4 *World;
bool Visible;
};
};
};
#endif

View File

@ -0,0 +1,29 @@
#pragma once
#ifndef MODELINFO_h
#define MODELINFO_h
//#include "../Engine.h"
#include "..\Core\CoreIncludes.h"
#include "..\Core\Buffer.h"
//#include "OysterMath.h"
//#include "ICollideable.h"
using namespace Oyster::Math;
namespace Oyster
{
namespace Render
{
struct ModelInfo
{
std::vector<ID3D11ShaderResourceView*> Material;
Oyster::Buffer Vertices,Indecies;
bool Indexed;
int VertexCount;
};
};
};
#endif

View File

@ -0,0 +1,165 @@
#include "Textbox.h"
using namespace Oyster::Render;
//int Textbox::NumTextfields=0;
Oyster::Buffer Textbox::TextBuffer;
int Textbox::NumLetters;
//std::vector<TextInstanceData> Textbox::TextInstances;
ID3D11ShaderResourceView* Textbox::Texture=NULL;
bool Textbox::Init()
{
//NumTextfields = 0;
//NumVertices = 0;
//HRESULT test=HRESULT_FAI
if(FAILED(CreateVertexBuffer()))
{
return false;
}
//update(_str, _pos);
return true;
//return true;
}
bool Textbox::SetTexture(const char* _file)
{
if(FAILED(D3DX11CreateShaderResourceViewFromFileA(Oyster::Core::Device, _file, NULL, NULL, &Texture, NULL)))
{
return false;
}
return true;
}
bool Textbox::UpdateTextField(std::string _str)
{
//DEPRECATED
//Update(_str);
return false;
/*UINT _id=TextInstances.size();
//TextInstances.resize(_id+1);
Text2D newD;
TextInstances.push_back(newD);
if(FAILED(CreateTextfield(_id)))
{
return false;
}
Update(_id, _str, _pos);
TextInstances[_id].Visible=true;
TextInstances[_id].World=Float4x4::identity;
NumTextfields++;
return true;*/
}
HRESULT Textbox::CreateVertexBuffer()
{
HRESULT result;
//Create vertices
/*
std::vector<TextData> mVertices;
mVertices.resize(4);
D3DXVECTOR3 testloc=D3DXVECTOR3(0,0,0);
mVertices[0].pos = testloc+D3DXVECTOR3(0.0f, 0.0f, 0.0f);
mVertices[1].pos = testloc+D3DXVECTOR3(TEXT_SIZE, 0.0f, 0.0f);
mVertices[2].pos = testloc+D3DXVECTOR3(0.0f, TEXT_SIZE, 0.0f);
mVertices[3].pos = testloc+D3DXVECTOR3(TEXT_SIZE, TEXT_SIZE, 0.0f);
float normaloffset=(1.0f/TEXT_NR_LETTERS);
mVertices[0].uv=D3DXVECTOR2(normaloffset,1);
mVertices[1].uv=D3DXVECTOR2(0,1);
mVertices[2].uv=D3DXVECTOR2(normaloffset,0);
mVertices[3].uv=D3DXVECTOR2(0,0);
*/
//Oyster::Buffer::BUFFER_INIT_DESC desc;
//desc.ElementSize=sizeof(TextData);
//desc.NumElements = mVertices.size();
//desc.Type = Oyster::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
//desc.Usage = Oyster::Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
//desc.InitData = &mVertices[0];
//result=TextBuffer.Init(desc);
//NumVertices=mVertices.size();
//TextInstances[_id].NumLetters=0;
/*Text2D tmp;
tmp.coff=0;
tmp.offset=0;
tmp.Pos=Float2(0,0);*/
Oyster::Buffer::BUFFER_INIT_DESC desc;
desc.ElementSize=sizeof(Text2D);
desc.NumElements = MAX_LETTER_COUNT;
desc.Type = Oyster::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
desc.Usage = Oyster::Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
desc.InitData = 0;
result=TextBuffer.Init(desc);
NumLetters=0;
return result;
}
HRESULT Textbox::CreateTextfield(int _id)
{
HRESULT result=E_FAIL;
/*if (TextInstances.size()>_id)
{
TextInstances[_id].NumLetters=0;
Oyster::Buffer::BUFFER_INIT_DESC desc;
desc.ElementSize=sizeof(Text2D);
desc.NumElements = MAX_LETTER_COUNT;
desc.Type = Oyster::Buffer::BUFFER_TYPE::VERTEX_BUFFER;
desc.Usage = Oyster::Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
desc.InitData = 0;
result=TextInstances[_id].InstanceBuffer.Init(desc);
}*/
return result;
}
void Textbox::Update(std::string _str, float _xscale)
{
UINT instances=0;
Text2D tmpInst;
void* dest = TextBuffer.Map();
Text2D* dataView = reinterpret_cast<Text2D*>(dest);
//tmpInst.charOffset=_pos;
for (unsigned int i=0; i<_str.length(); i++)
{
tmpInst.coff=(1.0f/TEXT_NR_LETTERS);
tmpInst.offset=(_str[i]-32);
tmpInst.Pos=i*(0.005f*_xscale);
//float tst=getCharID(_str[i]);
//tmpInst.offset=tst;
//tmpInst.charOffset.x=_pos.x-i*TEXT_SIZE;
//tmpInst.data=tst;
dataView[instances]=tmpInst;
instances++;
}
NumLetters=instances;
//TextInstances[_id].NumLetters=instances;
TextBuffer.Unmap();
}
float Textbox::getCharID(char _in)
{
//int charid=_in;
//float charid=((_in-'0')-32);
return ((_in-32)*(1.0f/TEXT_NR_LETTERS));
//return _in-'0';
}
void Textbox::Apply(int _id)
{
//Check if the subset exists, so we don't try to pain something that isn't there resulting in a crash
//if (NumTextfields>_id)
//{
//Oyster::Core::DeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
//Set the size of each vertex "jump", and the start point for the shader
//unsigned int strides[2];
//offsets start at 0.
//unsigned int offsets[2]={0,0};
//Load the strides with the size of each type
//strides[0] = sizeof(TextData);
//strides[1] = sizeof(PerCharData);
//Create an array which points to the buffers needed.
//ID3D11Buffer* bufferPointers[2];
//bufferPointers[0] = TextBuffer;
//bufferPointers[1] = TextInstances[_id].InstanceBuffer;
//Load the vertex buffer into the shader
//Oyster::Core::DeviceContext->IASetVertexBuffers(0, 2, bufferPointers, strides, offsets);
//Get the basic info of the technique that's loaded
//}
}

View File

@ -0,0 +1,67 @@
#pragma once
#include "..\Engine.h"
const int MAX_LETTER_COUNT=60;
const int TEXT_NR_LETTERS=95;
const float TEXT_SIZE=2.5;
struct Text2D
{
Oyster::Math::Float Pos;
int offset;
float coff;
};
/*struct TextInstanceData
{
Oyster::Buffer InstanceBuffer;
bool Visible;
int NumLetters;
Oyster::Math::Float4x4 World;
};*/
/*struct TextData
{
Oyster::Math::Float3 pos;
Oyster::Math::Float2 uv;
};
struct PerCharData
{
float data;
Oyster::Math::Float3 charOffset;
};
struct TextInstanceData
{
Oyster::Buffer InstanceBuffer;
bool Visible;
int NumLetters;
Oyster::Math::Float4x4 World;
};*/
namespace Oyster
{
namespace Render
{
class Textbox
{
private:
static float getCharID(char _in);
static HRESULT CreateVertexBuffer();
static HRESULT CreateTextfield(int _id);
public:
//static Oyster::Buffer TextBuffer;
//static int NumVertices;
//static std::vector<TextInstanceData> TextInstances;
static Oyster::Buffer TextBuffer;
static int NumLetters;
static ID3D11ShaderResourceView* Texture;
static bool Init();
static bool UpdateTextField(std::string _str);
static bool SetTexture(const char* _file);
//Updates a textbox with the certain id
static void Update(std::string _str, float _scale);
//Removes all old instances and recreates it with the input data
static HRESULT Reset(int _count, std::string* _str, Float3* _pos);
static void Apply(int _id);
};
}
}

View File

@ -0,0 +1,44 @@
#include "Buffers.h"
namespace Oyster
{
namespace Resources
{
Buffer Buffers::V2DSprites = Buffer();
Buffer Buffers::CbufferVS = Buffer();
Buffer Buffers::CBufferGs = Buffer();
Buffer Buffers::CBufferPipelineCs = Buffer();
void Buffers::Init()
{
Buffer::BUFFER_INIT_DESC desc;
desc.ElementSize=sizeof(Math::Float2);
desc.NumElements=1;
desc.Type = Buffer::BUFFER_TYPE::VERTEX_BUFFER;
desc.Usage = Buffer::BUFFER_USAGE::BUFFER_DEFAULT;
desc.InitData = &Math::Float2(0,0);
V2DSprites.Init(desc);
desc.Type=Buffer::BUFFER_TYPE::CONSTANT_BUFFER_VS;
desc.Usage = Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
desc.ElementSize=sizeof(Math::Float4x4);
desc.InitData=0;
CbufferVS.Init(desc);
desc.Type = Buffer::BUFFER_TYPE::CONSTANT_BUFFER_GS;
CBufferGs.Init(desc);
desc.ElementSize=sizeof(Oyster::Resources::BufferDefinitions::LightStructureBuffer);
desc.NumElements=1;
desc.Type = Buffer::BUFFER_TYPE::CONSTANT_BUFFER_CS;
desc.Usage = Buffer::BUFFER_USAGE::BUFFER_CPU_WRITE_DISCARD;
desc.InitData = NULL;
CBufferPipelineCs.Init(desc);
}
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "../EngineIncludes.h"
namespace Oyster
{
namespace Resources
{
struct Buffers
{
static Buffer V2DSprites;
static Buffer CbufferVS;
static Buffer CBufferGs;
static Buffer CBufferPipelineCs;
static void Init();
};
}
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "..\EngineIncludes.h"
namespace Oyster
{
namespace Resources
{
namespace BufferDefinitions
{
struct LightStructureBuffer
{
::Oyster::Math::Float4x4 viewMatrix, projectionMatrix;
::LinearAlgebra::Vector3<unsigned int> numDispatches;
unsigned int reservedPadding;
};
struct ScreenTileFrustrum
{
::Oyster::Math::Float rawElement[6 * 4];
};
class PointLightDescription
{
public:
struct{ ::Oyster::Math::Float3 center; ::Oyster::Math::Float radius; } pos;
::Oyster::Math::Float3 color;
::Oyster::Math::Float intensty;
};
};
}
}

View File

@ -0,0 +1,47 @@
#include "Manager.h"
std::unordered_map< std::string, Oyster::Render::ModelInfo*> Oyster::Resources::Manager::loadedModels = std::unordered_map< std::string, Oyster::Render::ModelInfo*>();
Oyster::Render::Model* Oyster::Resources::Manager::LoadModel(std::string Filename, Matrix Scale)
{
//TODO: Add redundncy sheck, to ensure not recreating model
//Loop to find filename
//If found Return Model
//else Create Model
Oyster::FileLoaders::ObjReader *reader = Oyster::FileLoaders::ObjReader::LoadFile(Filename, Scale);
Oyster::FileLoaders::ObjReader::Vertex** vertex = new Oyster::FileLoaders::ObjReader::Vertex*[1];
int vcount;
std::map<std::string,ID3D11ShaderResourceView *> textures;
reader->GetVertexData( vertex, vcount, textures );
Oyster::Buffer::BUFFER_INIT_DESC desc;
desc.ElementSize=sizeof(Oyster::FileLoaders::ObjReader::Vertex);
desc.NumElements = vcount;
desc.InitData = *vertex;
desc.Type = Oyster::Buffer::VERTEX_BUFFER;
desc.Usage = Oyster::Buffer::BUFFER_DEFAULT;
ID3D11ShaderResourceView *srv = textures["Diffuse"];
Oyster::Render::ModelInfo* m = new Oyster::Render::ModelInfo();
m->Vertices = *(Oyster::Engine::Init::Buffers::CreateBuffer(desc));
m->VertexCount = vcount;
m->Material.push_back(srv);
srv = textures["Specular"];
m->Material.push_back(srv);
srv = textures["Glow"];
m->Material.push_back(srv);
m->Indexed=false;
Oyster::Render::Model* model = new Oyster::Render::Model();
model->info=m;
model->Visible = true;
model->World = &Oyster::Math::Float4x4(Oyster::Math::Float4x4::identity);
return model;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "../EngineIncludes.h"
#include <unordered_map>
namespace Oyster
{
namespace Resources
{
struct Manager
{
//Expects to be deleted either trough manager or after a clean
static Oyster::Render::Model* LoadModel(std::string Filename, Matrix Scale);
static void Clean();
private:
static std::unordered_map< std::string, Oyster::Render::ModelInfo*> loadedModels;
};
}
}

View File

@ -0,0 +1,228 @@
#include "PipelineResources.h"
using namespace Oyster::Resources;
ID3D11UnorderedAccessView* PipeLineResourses::TempUav = 0;
ID3D11ShaderResourceView* PipeLineResourses::TempSrv = 0;
ID3D11ShaderResourceView* PipeLineResourses::GeometryOut[5] = {0};
ID3D11RenderTargetView* PipeLineResourses::GeometryTarget[5] = {0};
ID3D11ShaderResourceView* PipeLineResourses::ComputeResources[4] = {0};
Oyster::Buffer* PipeLineResourses::Resources[2] = {0};
ID3D11ShaderResourceView* PipeLineResourses::LightOut[4] = {0};
ID3D11UnorderedAccessView* PipeLineResourses::LightTarget[4] = {0};
ID3D11RenderTargetView* PipeLineResourses::RtvNulls[16] = {0};
ID3D11ShaderResourceView* PipeLineResourses::SrvNulls[16] = {0};
ID3D11UnorderedAccessView* PipeLineResourses::uavNULL[16] = {0};
Oyster::Collision::Frustrum* PipeLineResourses::SubFrustrums = 0;
int PipeLineResourses::FrustrumSize = 0;
LinearAlgebra::Vector3<unsigned int> PipeLineResourses::FrustrumDimensions = LinearAlgebra::Vector3<unsigned int>();
Oyster::Resources::BufferDefinitions::LightStructureBuffer PipeLineResourses::LightData = Oyster::Resources::BufferDefinitions::LightStructureBuffer();
void PipeLineResourses::Init()
{
InitGeometry();
InitSSAOData();
InitSubFrustrums();
InitPointLights();
InitLightData();
InitLighting();
}
void PipeLineResourses::InitGeometry()
{
D3D11_TEXTURE2D_DESC Tdesc;
Tdesc.Width = Oyster::Window::Size.left;
Tdesc.Height = Oyster::Window::Size.bottom;
Tdesc.MipLevels = Tdesc.ArraySize = 1;
Tdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
Tdesc.SampleDesc.Count = 1;
Tdesc.SampleDesc.Quality=0;
Tdesc.Usage = D3D11_USAGE_DEFAULT;
Tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
Tdesc.CPUAccessFlags = 0;
Tdesc.MiscFlags = 0;
ID3D11Texture2D *pTexture;
HRESULT hr;
//Geometry stage resourses
for( int i = 0; i < 5; ++i )
{
hr = Oyster::Core::Device->CreateTexture2D( &Tdesc, NULL, &pTexture );
hr = Oyster::Core::Device->CreateShaderResourceView(pTexture,0,&GeometryOut[i]);
hr = Oyster::Core::Device->CreateRenderTargetView(pTexture,0,&GeometryTarget[i]);
pTexture->Release();
}
}
void PipeLineResourses::InitSSAOData()
{
//create Half Spheres and Random Data
Oyster::Buffer::BUFFER_INIT_DESC desc;
HRESULT hr;
int NrOfSamples = Oyster::Engine::States::GetNrOfSSAOSamples();
int SampleSpread = Oyster::Engine::States::GetSSAOSampleSpread();
Oyster::Math::Vector3* kernel = new Oyster::Math::Vector3[ NrOfSamples ];
Oyster::Math::Vector3* random = new Oyster::Math::Vector3[ SampleSpread ];
for(int i = 0; i < NrOfSamples; ++i)
{
kernel[i] = Oyster::Math::Vector3::null;
while( kernel[i] == Oyster::Math::Vector3::null )
{
kernel[i] = Oyster::Math::Vector3(
(float)rand() / (RAND_MAX + 1) * (1 - -1) + -1,
(float)rand() / (RAND_MAX + 1) * (1 - -1) + -1,
(float)rand() / (RAND_MAX + 1) * (1 - 0) + 0);
}
kernel[i].normalize();
float scale = float(i) / float(NrOfSamples);
scale = (0.1f*(1 - scale * scale) + 1.0f *( scale * scale));
kernel[i] *= scale;
if( i < SampleSpread)
{
random[i] = Oyster::Math::Vector3::null;
while( random[i] == Oyster::Math::Vector3::null )
{
random[i] = Oyster::Math::Vector3(
(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,
(float)rand() / (RAND_MAX + 1) * (1 - -1)+ -1,
0.0f);
}
random[i].normalize();
}
}
D3D11_TEXTURE1D_DESC T1desc;
T1desc.Width = NrOfSamples;
T1desc.MipLevels = T1desc.ArraySize = 1;
T1desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
T1desc.Usage = D3D11_USAGE_DEFAULT;
T1desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
T1desc.CPUAccessFlags = 0;
T1desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA sphere;
sphere.pSysMem = kernel;
D3D11_SUBRESOURCE_DATA rnd;
rnd.pSysMem = random;
ID3D11Texture1D *pTexture1[2];
hr = Oyster::Core::Device->CreateTexture1D( &T1desc, &sphere, &pTexture1[0] );
hr = Oyster::Core::Device->CreateShaderResourceView( pTexture1[0], 0, &ComputeResources[3] );
pTexture1[0]->Release();
delete[] kernel;
T1desc.Width = SampleSpread;
hr = Oyster::Core::Device->CreateTexture1D( &T1desc, &rnd, &pTexture1[1] );
hr = Oyster::Core::Device->CreateShaderResourceView( (pTexture1[1]), 0, &ComputeResources[2] );
pTexture1[1]->Release();
delete[] random;
}
void PipeLineResourses::InitSubFrustrums()
{
FrustrumDimensions.x = (::Oyster::Window::Size.left + 15U) / 16U;
FrustrumDimensions.y = (::Oyster::Window::Size.bottom + 15U) / 16U;
FrustrumDimensions.z = 1;
FrustrumSize = FrustrumDimensions.x * FrustrumDimensions.y * FrustrumDimensions.z;
if(SubFrustrums!=0)
delete[] SubFrustrums;
SubFrustrums = new Frustrum[ FrustrumSize ];
Oyster::Buffer::BUFFER_INIT_DESC desc;
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
//buffer description for SubFrustrums
desc.Usage = Oyster::Buffer::BUFFER_CPU_WRITE_DISCARD;
desc.Type = Oyster::Buffer::STRUCTURED_BUFFER;
desc.ElementSize = sizeof( ::Oyster::Resources::BufferDefinitions::ScreenTileFrustrum);
desc.NumElements = FrustrumSize;
desc.InitData = NULL;
//create matching srv
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = FrustrumSize;
PipeLineResourses::Resources[0] = Oyster::Engine::Init::Buffers::CreateBuffer(desc);
HRESULT hr = Oyster::Core::Device->CreateShaderResourceView( *PipeLineResourses::Resources[0], &srvDesc, &Oyster::Resources::PipeLineResourses::ComputeResources[0] );
}
void PipeLineResourses::InitPointLights()
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
Oyster::Buffer::BUFFER_INIT_DESC desc;
HRESULT hr;
//buffer description for pointlight
desc.Usage = Oyster::Buffer::BUFFER_CPU_WRITE_DISCARD;
desc.Type = Oyster::Buffer::STRUCTURED_BUFFER;
desc.ElementSize = sizeof(Oyster::Resources::BufferDefinitions::PointLightDescription);
desc.NumElements = Oyster::Engine::States::GetMaxPointlights();
desc.InitData = NULL;
PipeLineResourses::Resources[1] = Oyster::Engine::Init::Buffers::CreateBuffer(desc);
//create matching srv
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = Oyster::Engine::States::GetMaxPointlights();
hr = Oyster::Core::Device->CreateShaderResourceView( *PipeLineResourses::Resources[1], &srvDesc, &Oyster::Resources::PipeLineResourses::ComputeResources[1] );
}
void PipeLineResourses::InitLightData()
{
LightData.numDispatches = FrustrumDimensions;
}
void PipeLineResourses::InitLighting()
{
D3D11_TEXTURE2D_DESC Tdesc;
Tdesc.Width = Oyster::Window::Size.left;
Tdesc.Height = Oyster::Window::Size.bottom;
Tdesc.MipLevels = Tdesc.ArraySize = 1;
Tdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
Tdesc.SampleDesc.Count = 1;
Tdesc.SampleDesc.Quality=0;
Tdesc.Usage = D3D11_USAGE_DEFAULT;
Tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
Tdesc.CPUAccessFlags = 0;
Tdesc.MiscFlags = 0;
ID3D11Texture2D *pTexture;
HRESULT hr;
for(int i = 0; i < 4; ++i )
{
hr = Oyster::Core::Device->CreateTexture2D( &Tdesc, NULL, &pTexture );
hr = Oyster::Core::Device->CreateShaderResourceView( pTexture, 0, &(LightOut[i]) );
hr = Oyster::Core::Device->CreateUnorderedAccessView( pTexture, 0, &(LightTarget[i]) );
pTexture->Release();
}
hr = Oyster::Core::Device->CreateTexture2D( &Tdesc, NULL, &pTexture );
hr = Oyster::Core::Device->CreateShaderResourceView( pTexture, 0, &TempSrv );
hr = Oyster::Core::Device->CreateUnorderedAccessView( pTexture, 0, &TempUav );
pTexture->Release();
}

View File

@ -0,0 +1,66 @@
#pragma once
#ifndef PipeLineResources_H
#define PipeLineResources_H
#include "..\EngineIncludes.h"
namespace Oyster
{
namespace Resources
{
struct PipeLineResourses
{
//0 = Diffuse
//1 = Specular
//2 = Glow
//3 = Pos
//4 = Normal
static ID3D11ShaderResourceView* GeometryOut[5];
static ID3D11RenderTargetView* GeometryTarget[5];
//0 = TileBuffer
//1 = PointList
//2 = Random
//3 = Sphere
static ID3D11ShaderResourceView* ComputeResources[4];
static Oyster::Buffer* Resources[2];
//0 = Diffuse
//1 = Specular
//2 = Glow
//3 = SSAO
static ID3D11ShaderResourceView* LightOut[4];
static ID3D11UnorderedAccessView* LightTarget[4];
//0 = BlurTempStorage
static ID3D11UnorderedAccessView* TempUav;
static ID3D11ShaderResourceView* TempSrv;
static ID3D11RenderTargetView* RtvNulls[16];
static ID3D11ShaderResourceView* SrvNulls[16];
static ID3D11UnorderedAccessView* uavNULL[16];
static Oyster::Collision::Frustrum* SubFrustrums;
static int FrustrumSize;
static LinearAlgebra::Vector3<unsigned int> FrustrumDimensions;
static Oyster::Resources::BufferDefinitions::LightStructureBuffer LightData;
static void Init();
static void InitGeometry();
static void InitSSAOData();
static void InitSubFrustrums();
static void InitPointLights();
static void InitLightData();
static void InitLighting();
};
}
}
#endif

View File

@ -0,0 +1,100 @@
#include "ShaderEffects.h"
namespace Oyster
{
namespace Resources
{
Shader::ShaderEffect ShaderEffects::BasicSprite = Shader::ShaderEffect();
Shader::ShaderEffect ShaderEffects::Text2DEffect = Shader::ShaderEffect();
Shader::ShaderEffect ShaderEffects::ModelEffect = Shader::ShaderEffect();
void ShaderEffects::Init()
{
BasicSprite.IAStage.Topology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
BasicSprite.Shaders.Vertex = Oyster::Shader::Get::GetVertex("2D");
BasicSprite.Shaders.Geometry = Oyster::Shader::Get::GetGeometry("2D");
BasicSprite.Shaders.Pixel = Oyster::Shader::Get::GetPixel("Texture0");
D3D11_BLEND_DESC blendDesc;
blendDesc.AlphaToCoverageEnable=false;
blendDesc.IndependentBlendEnable=false;
blendDesc.RenderTarget[0].BlendEnable=true;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_MAX;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
ID3D11BlendState* blender;
Oyster::Core::Device->CreateBlendState(&blendDesc,&blender);
BasicSprite.RenderStates.BlendState = blender;
ID3D11InputLayout* layout;
Oyster::Shader::CreateInputLayout(SpriteVertexDesc,1,Oyster::Shader::Get::GetVertex("2D"),layout);
BasicSprite.IAStage.Layout = layout;
Text2DEffect.IAStage.Topology=D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
Text2DEffect.Shaders.Vertex = Oyster::Shader::Get::GetVertex("Text");
Text2DEffect.Shaders.Geometry = Oyster::Shader::Get::GetGeometry("Text");
Text2DEffect.Shaders.Pixel = Oyster::Shader::Get::GetPixel("Texture0");
Oyster::Shader::CreateInputLayout(Text2DDesc,3,Oyster::Shader::Get::GetVertex("Text"),layout);
Text2DEffect.IAStage.Layout = layout;
blendDesc.AlphaToCoverageEnable = true;
Oyster::Core::Device->CreateBlendState(&blendDesc,&blender);
Text2DEffect.RenderStates.BlendState = blender;
ModelEffect.IAStage.Topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
Oyster::Shader::CreateInputLayout(ModelDesc,3,Oyster::Shader::Get::GetVertex("OBJ"),layout);
ModelEffect.IAStage.Layout = layout;
ModelEffect.Shaders.Vertex = Oyster::Shader::Get::GetVertex("OBJ");
ModelEffect.Shaders.Pixel = Oyster::Shader::Get::GetPixel("OBJDEF");
Oyster::Buffer::BUFFER_INIT_DESC desc;
desc.ElementSize=sizeof(Oyster::Math::Float4x4);
desc.NumElements = 1;
desc.Usage = Oyster::Buffer::BUFFER_CPU_WRITE_DISCARD;
desc.Type = Oyster::Buffer::CONSTANT_BUFFER_VS;
desc.InitData = NULL;
ModelEffect.CBuffers.Vertex.push_back(Oyster::Engine::Init::Buffers::CreateBuffer(desc));
ModelEffect.CBuffers.Vertex.push_back(Oyster::Engine::Init::Buffers::CreateBuffer(desc));
//use Oyster::Resources::Buffers::CbufferVS for per object data
//perObject = Oyster::Engine::Init::Buffers::CreateBuffer(desc);
}
D3D11_INPUT_ELEMENT_DESC ShaderEffects::SpriteVertexDesc[1] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
D3D11_INPUT_ELEMENT_DESC ShaderEffects::Text2DDesc[3] =
{
{"Position",0, DXGI_FORMAT_R32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"Offset",0, DXGI_FORMAT_R32_SINT, 0, 4, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"CharOffset",0, DXGI_FORMAT_R32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
D3D11_INPUT_ELEMENT_DESC ShaderEffects::ModelDesc[3] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
}
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "../Engine.h"
#include "Buffers.h"
namespace Oyster
{
namespace Resources
{
struct ShaderEffects
{
static Oyster::Shader::ShaderEffect BasicSprite;
static Oyster::Shader::ShaderEffect Text2DEffect;
static Oyster::Shader::ShaderEffect ModelEffect;
static void Init();
static D3D11_INPUT_ELEMENT_DESC SpriteVertexDesc[1];
static D3D11_INPUT_ELEMENT_DESC Text2DDesc[3];
static D3D11_INPUT_ELEMENT_DESC ModelDesc[3];
};
}
}

View File

@ -0,0 +1,51 @@
struct Vertex2DIn
{
float2 Pos : Position;
};
cbuffer EveryObject2D : register(c0)
{
float4x4 Translation;
};
SamplerState LinearSampler : register(s0);
struct Pixel2DIn
{
float4 Pos : SV_Position;
float2 Uv : TEXCOORD;
};
Texture2D Material : register(t0);
float4 ApplyMaterial0(Pixel2DIn input) : SV_Target0
{
return Material.Sample(LinearSampler,input.Uv);
}
Vertex2DIn PassThrough(Vertex2DIn input)
{
return input;
}
[maxvertexcount(4)]
void PointToQuad(point Vertex2DIn input[1],inout TriangleStream<Pixel2DIn> Quads)
{
Pixel2DIn output;
output.Pos = mul(float4(-1,-1,0,1) ,Translation);
output.Uv = float2(0,1);
Quads.Append(output);
output.Pos = mul(float4(-1,1,0,1), Translation);
output.Uv = float2(0,0);
Quads.Append(output);
output.Pos = mul(float4(1,-1,0,1), Translation);
output.Uv = float2(1,1);
Quads.Append(output);
output.Pos = mul(float4(1,1,0,1), Translation);
output.Uv = float2(1,0);
Quads.Append(output);
}

View File

@ -0,0 +1,22 @@
cbuffer everyFrame : register(c0)
{
matrix VP;
}
cbuffer everyObject : register(c1)
{
matrix world;
}
Texture2D Diffuse :register(t0);
float4 VSScene(float4 input : POSITION) : SV_Position
{
//return input;
return mul(input,VP);
}
float4 PSScene(float4 input : SV_Position) : SV_Target0
{
return float4(0,1,0,1);
}

View File

@ -0,0 +1,52 @@
#ifndef COLLISIONMETHODS_HLSL
#define COLLISIONMETHODS_HLSL
struct Sphere
{
float3 center;
float radius;
};
struct Plane
{
float3 normal;
float phasing;
};
struct Frustrum
{
Plane leftPlane, rightPlane, bottomPlane, topPlane, nearPlane, farPlane;
};
bool intersects( uniform Frustrum f, uniform Sphere s )
{
float connectOffset;
connectOffset = dot( f.leftPlane.normal, s.center );
connectOffset += f.leftPlane.phasing;
if( connectOffset < -s.radius ) return false;
connectOffset = dot( f.rightPlane.normal, s.center );
connectOffset += f.rightPlane.phasing;
if( connectOffset < -s.radius ) return false;
connectOffset = dot( f.bottomPlane.normal, s.center );
connectOffset += f.bottomPlane.phasing;
if( connectOffset < -s.radius ) return false;
connectOffset = dot( f.topPlane.normal, s.center );
connectOffset += f.topPlane.phasing;
if( connectOffset < -s.radius ) return false;
connectOffset = dot( f.nearPlane.normal, s.center );
connectOffset += f.nearPlane.phasing;
if( connectOffset < -s.radius ) return false;
connectOffset = dot( f.farPlane.normal, s.center );
connectOffset += f.farPlane.phasing;
if( connectOffset < -s.radius ) return false;
return true;
}
#endif

View File

@ -0,0 +1,85 @@
Texture2D Diffuse : register(t0);
Texture2D Glow : register(t1);
RWTexture2D<float4> Output : register(u0);
cbuffer BlurrData : register(c0)
{
static const int blurRadius = 5;
static const float Weights[11] =
{
0.05f,0.05f,0.1f,0.1f,0.1f,0.2f,0.1f,0.1f,0.1f,0.05f,0.05f
};
};
[numthreads(32,32,1)]
void TryCompute(uint3 ThreadID : SV_DispatchThreadID)
{
Output[ThreadID.xy] = Diffuse[ThreadID.xy]*0.5f+Glow[ThreadID.xy]*Glow[ThreadID.xy].w;
}
#define N 128
#define gSize (N+2*blurRadius)
groupshared float4 gCache[gSize];
[numthreads(N,1,1)]
void BlurrHor(int3 ThreadID : SV_DispatchThreadID, int3 gThreadID : SV_GroupThreadID)
{
if(gThreadID.x < blurRadius)
{
int x = max(ThreadID.x-blurRadius,0);
gCache[gThreadID.x] = Diffuse[int2(x,ThreadID.y)];
}
if(gThreadID.x >= N-blurRadius)
{
int x = min(ThreadID.x+blurRadius,Diffuse.Length.x-1);
gCache[gThreadID.x+2*blurRadius] = Diffuse[int2(x,ThreadID.y)];
}
gCache[gThreadID.x+blurRadius] = Diffuse[min(ThreadID.xy,Diffuse.Length.xy-1)];
GroupMemoryBarrierWithGroupSync();
float4 blurCol = float4(0,0,0,0);
[unroll]
for(int i = -blurRadius; i <= blurRadius;++i)
{
int k = gThreadID.x + blurRadius + i;
blurCol +=Weights[i + blurRadius] * gCache[k];
}
Output[ThreadID.xy] = blurCol;
//Output[ThreadID.xy] = Diffuse[((ThreadID.xy))];
}
[numthreads(1,N,1)]
void BlurrVert(int3 ThreadID : SV_DispatchThreadID, int3 gThreadID : SV_GroupThreadID)
{
if(gThreadID.y < blurRadius)
{
int y = max(ThreadID.y-blurRadius,0);
gCache[gThreadID.y] = Diffuse[int2(ThreadID.x,y)];
}
if(gThreadID.y >= N-blurRadius)
{
int y = min(ThreadID.y+blurRadius,Diffuse.Length.y-1);
gCache[gThreadID.y+2*blurRadius] = Diffuse[int2(ThreadID.x,y)];
}
gCache[gThreadID.y+blurRadius] = Diffuse[min(ThreadID.xy,Diffuse.Length.xy-1)];
GroupMemoryBarrierWithGroupSync();
float4 blurCol = float4(0,0,0,0);
[unroll]
for(int i = -blurRadius; i <= blurRadius;++i)
{
int k = gThreadID.y + blurRadius + i;
blurCol +=Weights[i + blurRadius] * gCache[k];
}
Output[ThreadID.xy] = blurCol;
//Output[ThreadID.xy] = Diffuse[((ThreadID.xy))];
}

View File

@ -0,0 +1,129 @@
struct VertexIn
{
float3 Pos : Position;
};
cbuffer EveryObject2D : register(c0)
{
float4x4 VP;
};
struct Pixel2DIn
{
float4 Pos : SV_Position;
float2 Uv : TEXCOORD;
};
const static float Width = 5.0f;
VertexIn PassThrough(VertexIn input)
{
return input;
}
[maxvertexcount(16)]
void Lazer(line VertexIn input[2],inout TriangleStream<Pixel2DIn> Quads)
{
//build coordinate system
float3 r =normalize(input[1].Pos-input[0].Pos);
float3 s = abs(r);
//set s ortogonal to r
if(s.x<s.y && s.x<s.z)
s = float3(0,-r.z,r.y);
else if(s.y<s.x && s.y<s.z)
s = float3(-r.z,0,r.x);
else
s = float3(-r.y,r.x,0);
float3 t = cross(r,s);
Pixel2DIn output;
//create the corners of the plane rxs Forward Facing
//top left
output.Pos = mul(float4( input[0].Pos + Width*s,1),VP);
output.Uv = float2(0,1);
Quads.Append(output);
//botom left
output.Pos = mul(float4( input[0].Pos - Width*s,1),VP);
output.Uv = float2(0,0);
Quads.Append(output);
//top right
output.Pos = mul(float4( input[1].Pos + Width*s,1),VP);
output.Uv = float2(1,1);
Quads.Append(output);
//botom right
output.Pos =mul(float4( input[1].Pos - Width*s,1),VP);
output.Uv = float2(1,0);
Quads.Append(output);
Quads.RestartStrip();
//create the corners of the plane rxs BackWard Facing
//top left
output.Pos = mul(float4( input[0].Pos + Width*s,1),VP);
output.Uv = float2(0,1);
Quads.Append(output);
//top right
output.Pos = mul(float4( input[1].Pos + Width*s,1),VP);
output.Uv = float2(1,1);
Quads.Append(output);
//botom left
output.Pos = mul(float4( input[0].Pos - Width*s,1),VP);
output.Uv = float2(0,0);
Quads.Append(output);
//botom right
output.Pos =mul(float4( input[1].Pos - Width*s,1),VP);
output.Uv = float2(1,0);
Quads.Append(output);
Quads.RestartStrip();
//create the corners of the plane rxt Forward Facing
//top left
output.Pos = mul(float4( input[0].Pos + Width*t,1),VP);
output.Uv = float2(0,1);
Quads.Append(output);
//botom left
output.Pos = mul(float4( input[0].Pos - Width*t,1),VP);
output.Uv = float2(0,0);
Quads.Append(output);
//top right
output.Pos = mul(float4( input[1].Pos + Width*t,1),VP);
output.Uv = float2(1,1);
Quads.Append(output);
//botom right
output.Pos =mul(float4( input[1].Pos - Width*t,1),VP);
output.Uv = float2(1,0);
Quads.Append(output);
Quads.RestartStrip();
//create the corners of the plane rxt Forward Facing
//top left
output.Pos = mul(float4( input[0].Pos + Width*t,1),VP);
output.Uv = float2(0,1);
Quads.Append(output);
//top right
output.Pos = mul(float4( input[1].Pos + Width*t,1),VP);
output.Uv = float2(1,1);
Quads.Append(output);
//botom left
output.Pos = mul(float4( input[0].Pos - Width*t,1),VP);
output.Uv = float2(0,0);
Quads.Append(output);
//botom right
output.Pos =mul(float4( input[1].Pos - Width*t,1),VP);
output.Uv = float2(1,0);
Quads.Append(output);
}

View File

@ -0,0 +1,151 @@
// Personal notes and trail of thought //////////////////////////////
/*
Light is flux ( latin fluxus ; flow )
(F1) Flux density : amount of flow through a cross section (A)
(L) Luminosity: property of light, amount of light output per time. Equivalent with the Watt unit.
(A) Area as a function of range(r).
A[r] = 4*PI*r^2
F1 = L / A[r] = L / ( 4*PI*r^2 )
_Attenuation_
Attenuation is the gradual loss in intensity of any kind of flux through a medium. ~ Wikipedia
It is also dependant of BOTH medium material and type of Flux. Attenuation( soft Tissue, Light ) != Attenuation( soft Tissue, Xray ).
Hm'Yeah .. lets not use that. And SHAME to those who use that word carelessly in computer graphics!!!
_Attenuation_coefficient_
The linear intensity loss of a narrow beam through a medium.
Hm .. This sounds CG delicious :)
F2 = L / ( AttCoeff * r )
_Total:_
F = F1 + F2 = L / ( 4*PI*r^2 ) + L / ( AttCoeff * r ) = L / ( AttCoeff*r + 4*PI*r^2 )
May vary between light spreadTypes -------^^^^
L = ( Red Luminosity, Green Luminosity, Blue Luminosity, Spread )
F = ( Red Density, Green Density, Blue Density ) = L.rgb / (AttCoeff*r + L.s^2)
AttCoeff : property of Enviroment
Ambience Light : property of Enviroment
*/
#ifndef LIGHTMATERIALMETHODS_HLSL
#define LIGHTMATERIALMETHODS_HLSL
#include "CollisionMethods.hlsl"
#define PI 3.1415926535897932384626433832795f
#define POINTLIGHT_SPREADCOEFF 12.566370614359172953850573533118f
struct PointLight
{
Sphere pos;
float3 color;
float intensity;
};
void accumulateLight( inout float3 diffusePixel, inout float3 specularPixel, uniform in PointLight lightV, uniform in float exposure, uniform in float specularGloss, uniform in float3 pixelPosV, uniform in float3 normalV )
{
float3 toLightVecV = lightV.pos.center - pixelPosV;
float range = length( toLightVecV );
if( !(range <= lightV.pos.radius ) )
{
return;
}
toLightVecV /= range;
float3 illum = lightV.color;
illum *= (exposure * lightV.intensity) / ( range + (POINTLIGHT_SPREADCOEFF * pow(range, 2.0f)) ); // light density on all rgb channels
// calculating and adding the DiffuseCoefficient
float coeff = max( dot(toLightVecV, normalV), 0.0f );
diffusePixel += illum * coeff;
if( coeff > 0.0f )
{ // calculating and adding the SpecularCoefficient
coeff = max( dot( reflect(-toLightVecV, normalV), normalize(-pixelPosV) ), 0.0f );
specularPixel += illum * pow( coeff, specularGloss );
}
}
// ------------------ old below
/*
struct Medium
{
float3 ambienceLuminosity;
float attenuationCoeff;
};
struct Light
{
matrix worldToLightVolume;
float3 luminosity;
float spreadCoeff;
float4 orientation;
};
// returns light density per rgb channel
float3 calcLightDensity( uniform float rangeW, uniform Light light, uniform Medium enviroment )
{ return light.luminosity / ( (enviroment.attenuationCoeff * rangeW) + (light.spreadCoeff * pow(rangeW, 2.0f)) ); }
// returns light density per rgb channel
float3 calcLightDensity( uniform float rangeW, uniform Light light )
{ return light.luminosity / ( rangeW + (light.spreadCoeff * pow(rangeW, 2.0f)) ); }
float calcDiffuseCoeff( uniform float3 normalW, uniform float3 toLightVecW )
{ return max( dot( toLightVecW, normalW ), 0.0f ); }
float calcSpecularCoeff( uniform float3 normalW, uniform float3 toLightVecW, uniform float3 toObserverVecW )
{ return max( dot( reflect( -toLightVecW, normalW ), toObserverVecW ), 0.0f ); }
/////////////////////////////////////////////////////////////////////
// SHADOW SAMPLING
/////////////////////////////////////////////////////////////////////
/*SamplerComparisonState shadowSampling
{
Filter = COMPARISON_MIN_MAG_MIP_POINT;
ComparisonFunc = LESS_EQUAL;
AddressU = BORDER;
AddressV = BORDER;
AddressW = BORDER;
BorderColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
};/**/
/*
SamplerState shadowSampling
{
Filter = MIN_MAG_MIP_POINT;
AddressU = BORDER;
AddressV = BORDER;
AddressW = BORDER;
BorderColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
};/**/
/*
void sampleShadowPCFx4( uniform float3 posW, uniform Light light, uniform Texture2D shadowMap, uniform float2 shadowMapResolution, out float lightExposure, out float range )
{
float4 value = mul( light.worldToLightVolume, float4(posW, 1.0f) );
value /= value.w;
float2 shadowUV = 0.5f*( float2(value.x, -value.y) + 1.0f );
float2 shadowUVDelta = 1.0f / shadowMapResolution;
range = value.z - 0.00390625f;
//lightExposure = shadowMap.SampleCmpLevelZero( shadowSampling, shadowUV, range ).r;
value.x = (float)shadowMap.Sample(shadowSampling, shadowUV ).r;
value.y = (float)shadowMap.Sample(shadowSampling, shadowUV + float2(shadowUVDelta.x, 0.0f) );
value.z = (float)shadowMap.Sample(shadowSampling, shadowUV + float2(0.0f, shadowUVDelta.y) );
value.w = (float)shadowMap.Sample(shadowSampling, shadowUV + shadowUVDelta );
value.x = range > value.x ? 0.0f : 1.0f; // 1.0f if lightRange is not lesser than range. Else 0.0f
value.y = range > value.y ? 0.0f : 1.0f;
value.z = range > value.z ? 0.0f : 1.0f;
value.w = range > value.w ? 0.0f : 1.0f;
range += 0.00390625f;
shadowUV = frac( shadowUV * shadowMapResolution );
lightExposure = lerp( lerp( value.x, value.y, shadowUV.x ), lerp( value.z, value.w, shadowUV.x ), shadowUV.y );
}
*/
#endif

View File

@ -0,0 +1,74 @@
cbuffer Rarely : register(c0)
{
matrix ViewProjection;
}
cbuffer everyFrame : register(c1)
{
matrix View;
}
cbuffer everyObject : register(c2)
{
matrix World;
}
Texture2D Diffuse :register(t0);
Texture2D Specular :register(t1);
Texture2D Glow :register(t2);
SamplerState LinearSampler : register(s0);
struct VSObjIn
{
float3 Pos : POSITION;
float3 Normal : NORMAL;
float2 UV : TEXCOORD;
};
struct PSObjIn
{
float4 Pos : SV_POSITION;
float3 WorldPos : POSITION;
float3 Normal : NORMAL;
float2 UV : TEXCOORD;
};
struct PSObjOut
{
float4 Diffuse : SV_Target0;
float4 Specular : SV_Target1;
float4 Glow : SV_Target2;
float4 Pos : SV_Target3;
float4 Normal : SV_Target4;
};
PSObjIn VSObj(VSObjIn input)
{
PSObjIn output;
matrix WV = mul( World, View );
matrix WVP = mul (World, ViewProjection );
output.Pos = mul( float4(input.Pos, 1), WVP );
output.WorldPos = mul( float4(input.Pos, 1), WV ).xyz;
output.Normal = mul( float4(input.Normal, 0), WV ).xyz;
output.UV = input.UV;
return output;
}
float4 PSObj (PSObjIn errors) : SV_Target0
{
return Diffuse.Sample( LinearSampler, errors.UV );
}
PSObjOut PSDefObj(PSObjIn inp)
{
PSObjOut outp;
outp.Pos = float4( inp.WorldPos, 1 );
outp.Normal = float4( normalize(inp.Normal), 0 ); // normalize since interpolation messes them up
outp.Diffuse = Diffuse.Sample( LinearSampler, inp.UV );
outp.Specular = Specular.Sample( LinearSampler, inp.UV );
outp.Glow = Glow.Sample( LinearSampler, inp.UV );
return outp;
}

View File

@ -0,0 +1,32 @@
//Texture2D pos : register(t3);
//Texture2D normal : register(t4);
Texture1D<float3> rand : register(t8);
Texture1D<float3> sphere : register(t9);
float SSAOperPixel( int2 pixel)
{
float3 rnd = rand[(pixel.x+pixel.y)%rand.Length.x];
float3 nvec = normal[pixel].xyz;
float3 tangent = normalize(rnd-nvec * dot(rnd, nvec));
float3 biTangent = cross(nvec,tangent);
float3x3 tbn; // = float3x3( nvec, tangent, normal);
tbn[0] =nvec;
tbn[1] =tangent;
tbn[2] =biTangent;
float occlusion = 0.0f;
for(int i=0;i<sphere.Length.x;++i)
{
float3 sampled = mul( tbn, sphere[i].xyz);
sample = sampled * SSAOSphereRadius + pos[pixel].xyz;
//test acumulate
float rangeCheck = abs(pos[pixel].z - sampled.z) < SSAOSphereRadius ? 1.0f : 0.0f;
occlusion += (sampled.z <= pos[pixel].z ? 1.0 : 0.0) * rangeCheck;
}
return 1.0 - (occlusion / sphere.Length.x);
}

View File

@ -0,0 +1,30 @@
F ..\Shaders\BasicDemo.hlsl
V VSScene VS
P PSScene PS
F ..\Shaders\Obj.hlsl
V VSObj OBJ
P PSObj OBJ
P PSDefObj OBJDEF
F ..\Shaders\2D.hlsl
V PassThrough 2D
G PointToQuad 2D
P ApplyMaterial0 Texture0
F ..\Shaders\Text.hlsl
V PassThroughText Text
G TextToQuad Text Text
F ..\Shaders\Deffered.hlsl
C TryCompute Comp
C BlurrHor BlurHorizontal
C BlurrVert BlurVertical
F ..\Shaders\Lazer.hlsl
V PassThrough LazerV
G Lazer LazerG
F ..\Shaders\TileBasedDeffered.hlsl
C lightComputer Pass0
C composingComputer Pass1

View File

@ -0,0 +1,77 @@
#include "2D.hlsl"
cbuffer TextPerObject : register(c0)
{
float4x4 gWorld;
};
Texture2D g_tex1 : register(t0);
struct TEXT_VS_IN
{
float3 pos : POSITION;
float2 texCoord : TEXCOORD;
float ch : CHAR;
float3 off: VOFFSET;
};
struct TEXT_VS_OUT
{
float4 pos : SV_POSITION;
float2 texCoord : TEXCOORD;
};
TEXT_VS_OUT TEXT_VS(TEXT_VS_IN vIn)
{
TEXT_VS_OUT vOut;
vOut.pos = mul(float4(vIn.pos+vIn.off, 1.0f), gWorld);
//Adding texCoord
vOut.texCoord = vIn.texCoord;
vOut.texCoord[0]+=vIn.ch;
return vOut;
}
float4 TEXT_PS(TEXT_VS_OUT pIn) : SV_Target0
{
return g_tex1.Sample(LinearSampler, pIn.texCoord);
}
struct Text2DIn
{
float Pos : Position;
int off : Offset;
float coff : CharOffset;
};
Text2DIn PassThroughText(Text2DIn input)
{
return input;
}
[maxvertexcount(4)]
void TextToQuad(point Text2DIn input[1],inout TriangleStream<Pixel2DIn> Quads)
{
float startoff=input[0].off*input[0].coff;
float endoff=startoff+input[0].coff;
Pixel2DIn output;
output.Pos = mul(float4(-1,-1,0,1), Translation);
output.Pos.x+=input[0].Pos;
output.Uv = float2(startoff,1);
Quads.Append(output);
output.Pos = mul(float4(-1,1,0,1), Translation);
output.Pos.x+=input[0].Pos;
output.Uv = float2(startoff,0);
Quads.Append(output);
output.Pos = mul(float4(1,-1,0,1), Translation);
output.Pos.x+=input[0].Pos;
output.Uv = float2(endoff,1);
Quads.Append(output);
output.Pos = mul(float4(1,1,0,1), Translation);
output.Pos.x+=input[0].Pos;
output.Uv = float2(endoff,0);
Quads.Append(output);
}

View File

@ -0,0 +1,224 @@
#include "LightMaterialMethods.hlsl"
#define BLOCKSIZE 16
#define NUMTHREADS 256
#define UINT_MAX 0xFFFFFFFF
#define FLOAT_MAX 3.402823466e+38
#define SSAOSphereRadius 10.0f
#define SPECULARITY_GLOSS_MAX 40.0f
Texture2D<float4> mapMaterialDiffuse : register( t0 );
Texture2D<float4> mapMaterialSpecular : register( t1 );
Texture2D<float4> mapGlow : register( t2 );
Texture2D<float4> mapPosV : register( t3 );
Texture2D<float4> mapNormalV : register( t4 );
Texture2D<float4> mapDepth : register( t5 );
StructuredBuffer<Frustrum> tileBuffer : register( t6 );
StructuredBuffer<PointLight> pointLightBuffer : register( t7 );
Texture1D<float3> rand : register( t8 );
Texture1D<float3> sphere : register( t9 );
RWTexture2D<float4> outputDiffuseIllum : register( u0 );
RWTexture2D<float4> outputSpecularIllum : register( u1 );
RWTexture2D<float4> outputGlowMap : register( u2 );
RWTexture2D<float4> outputSSAOMap : register( u3 );
cbuffer LightData : register( c0 )
{
float4x4 viewMatrix;
float4x4 projectionMatrix;
uint3 numDispatches;
uint reservedPadding;
};
// -- Shared Memory ------------------------------------------------- //
groupshared uint iMinDepth = UINT_MAX,
iMaxDepth = 0;
groupshared uint numVisiblePointLights = 0,
visiblePointlightIndex[1024];
// ------------------------------------------------------------------ //
[numthreads( BLOCKSIZE, BLOCKSIZE, 1 )]
void lightComputer( uint3 groupID : SV_GroupID,
uint3 groupThreadID : SV_GroupThreadID,
uint groupIndex : SV_GroupIndex,
uint3 dispatchThreadID : SV_DispatchThreadID )
{
uint dispatchIndex = dispatchThreadID.x + numDispatches.x * ( dispatchThreadID.y + (numDispatches.y * dispatchThreadID.z) );
float3 posV = mapPosV[dispatchThreadID.xy].xyz;
// store and load shared minDepth and maxDepth
float minDepth = 0.0f, maxDepth = 0.0f,
depth = length( posV );
{
uint uidepth = (uint)( depth * 1024.0f );
InterlockedMin( iMinDepth, uidepth );
InterlockedMax( iMaxDepth, uidepth );
GroupMemoryBarrierWithGroupSync();
minDepth = (float)( iMinDepth ) * 0.0009765625f;
maxDepth = (float)( iMaxDepth ) * 0.0009765625f;
}
// -- Switching to LightCulling ------------------------------------- //
{
Frustrum tile = tileBuffer[dispatchIndex];
// culling the tile's near and far to minDepth & maxDepth ( with tolerance )
tile.nearPlane.phasing = -(minDepth * 0.85f);
tile.farPlane.phasing = (maxDepth * 1.15f);
uint numPointLights = pointLightBuffer.Length.x,
numPass = (numPointLights + NUMTHREADS - 1) / NUMTHREADS;
numPass = min( numPass, 1024 / NUMTHREADS );
for( uint passI = 0; passI < numPass; ++passI )
{
uint lightIndex = (passI * NUMTHREADS) + groupIndex;
lightIndex = min( lightIndex, numPointLights );
if( lightIndex < numPointLights )
if( intersects(tile, pointLightBuffer[lightIndex].pos) )
{
uint offset;
InterlockedAdd( numVisiblePointLights, 1, offset );
visiblePointlightIndex[offset] = lightIndex;
}
}
}
GroupMemoryBarrierWithGroupSync();
uint2 maxDim = mapMaterialDiffuse.Length.xy;
if( dispatchThreadID.x < maxDim.x && dispatchThreadID.y < maxDim.y )
{
// -- Switching to per Pixel Light Accumulation --------------------- //
float specularGloss = mapMaterialSpecular[dispatchThreadID.xy].w * SPECULARITY_GLOSS_MAX;
float3 normalV = mapNormalV[dispatchThreadID.xy].xyz;
float3 diffuseLight = 0,
specularLight = 0;
float4 v = float4( 0.0f, 0.0f, 0.0f, 0.0f );
for( uint lightI = 0; lightI < numVisiblePointLights; ++lightI )
{ // for each light that might touch this pixel
uint lightIndex = visiblePointlightIndex[lightI];
PointLight light = pointLightBuffer[lightIndex]; // should be preloaded into groupshared methinks
v = mul( viewMatrix, float4(light.pos.center, 1.0f) );
light.pos.center = v.xyz / v.w;
v = mul(viewMatrix, float4(light.pos.radius, 0.0f, 0.0f, 0.0f) );
light.pos.radius = length( v.xyz );
float exposure = 1.0f;
accumulateLight( diffuseLight, specularLight, light, exposure, specularGloss, posV, normalV );
}
// -- Applying SSAO ---------------------------------------- Pär H. - //
float occlusion = 0.0f;
{ //create sample coordinate system
float4 rnd = float4( rand[groupIndex % rand.Length.x].xyz, 0.0f );
float4 tangent = float4( normalize(rnd.xyz - (normalV * dot(rnd.xyz, normalV))), 0.0f );
float4 biTangent = float4( cross(tangent.xyz, normalV), 0.0f );
float4x4 tbn = float4x4( biTangent,
tangent,
float4(normalV, 0.0f),
float4(posV, 1.0f) );
for( uint i = 0; i < sphere.Length.x; ++i )
{
//take sample from localspace to viewspace
float4 sampled = mul( float4(sphere[i].xyz,1), tbn);
//project sample to get uv.xy
float4 offset = float4(sampled);
offset = mul( offset, projectionMatrix );
offset.xy /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;
offset.y = 1.0f - offset.y;
// get depth from that point in viewspace
uint2 texCoord;
texCoord.x = (uint)(offset.x * (float)(mapMaterialDiffuse.Length.x));
texCoord.y = (uint)(offset.y * (float)(mapMaterialDiffuse.Length.y));
float sampleDepth = length(mapPosV[texCoord]);
float rangeDepth = mapPosV[texCoord].z;
//compare to depth from sample
float rangeCheck = (abs(depth - sampleDepth) < SSAOSphereRadius) ? 1.0f : 0.0f;
occlusion += (sampleDepth <= length(sampled) ? 1.0f : 0.0f) * rangeCheck;
}
occlusion /= (float)(sphere.Length.x);
occlusion = 1.0f - occlusion;
}
// -- Compile and write Light values to buffers --------------------- //
diffuseLight.xyz *= mapMaterialDiffuse[dispatchThreadID.xy].xyz;
specularLight.xyz *= mapMaterialSpecular[dispatchThreadID.xy].xyz;
float4 glow = mapGlow[dispatchThreadID.xy];
glow *= glow.w;
//specularLight.xyz += mapGlow[dispatchThreadID.xy].xyz;
outputDiffuseIllum[dispatchThreadID.xy] = float4( diffuseLight, 1.0f );
outputSpecularIllum[dispatchThreadID.xy] = float4( specularLight.xyz, 1 );
outputGlowMap[dispatchThreadID.xy] = float4( glow.xyz * glow.z, 1 );
outputSSAOMap[dispatchThreadID.xy] = float4( occlusion, occlusion, occlusion, 1 );
}
}
/* ------------------------------------------------------------------ //
Needs to split into two passes here. As a major Dispatch sync is
is warranted for crossDispatch datasharing.
// ------------------------------------------------------------------ */
Texture2D<float4> mapDiffuse : register( t0 );
Texture2D<float4> mapSpecular : register( t1 );
Texture2D<float4> Glow : register( t2 );
Texture2D<float4> mapSSAO : register( t3 );
RWTexture2D<float4> outputBackBuffer : register( u0 );
[numthreads( BLOCKSIZE, BLOCKSIZE, 1 )]
void composingComputer( uint3 groupID : SV_GroupID,
uint3 groupThreadID : SV_GroupThreadID,
uint groupIndex : SV_GroupIndex,
uint3 dispatchThreadID : SV_DispatchThreadID )
{
uint2 maxDim = mapDiffuse.Length.xy;
if( dispatchThreadID.x < maxDim.x && dispatchThreadID.y < maxDim.y )
{
// -- Switching to light-material compiling ------------------------- //
float3 diffuse = mapDiffuse[dispatchThreadID.xy].xyz;
float3 specular = mapSpecular[dispatchThreadID.xy].xyz;
float3 glow = Glow[dispatchThreadID.xy].xyz;
float SSAO = mapSSAO[dispatchThreadID.xy].x;
float3 I = diffuse * SSAO + specular * SSAO + glow * 0.5f;
//outputBackBuffer[dispatchThreadID.xy] = float4( SSAO,SSAO,SSAO, 1.0f );
//return;
uint2 midScreen = mapDiffuse.Length.xy / 2;
if( dispatchThreadID.x < midScreen.x )
{
if( dispatchThreadID.y < midScreen.y )
outputBackBuffer[dispatchThreadID.xy] = float4( I, 1.0f );
else
outputBackBuffer[dispatchThreadID.xy] = float4( diffuse + specular, 1.0f );
}
else
{
if( dispatchThreadID.y < midScreen.y )
outputBackBuffer[dispatchThreadID.xy] = float4( glow * 0.5f, 1.0f );
else
outputBackBuffer[dispatchThreadID.xy] = float4( SSAO, SSAO, SSAO, 1.0f );
}/**/
}
}

View File

@ -0,0 +1,253 @@
#include "Shader.h"
#include "../Core/Core.h"
#include "Utilities.h"
#include <fstream>
#include <sstream>
namespace Oyster
{
namespace
{
std::vector<ID3D11PixelShader*> PS;
std::map<std::string,int> PSMap;
std::vector<ID3D11GeometryShader*> GS;
std::map<std::string,int> GSMap;
std::vector<ID3D11ComputeShader*> CS;
std::map<std::string,int> CSMap;
std::vector<ID3D11VertexShader*> VS;
std::vector<ID3D10Blob*> VBlob;
std::map<std::string,int> VSMap;
std::stringstream log;
}
bool Oyster::Shader::InitShaders(const std::string &name)
{
std::ifstream input;
input.open(name.c_str());
std::string s, file,method;
std::vector<std::string> line;
if(!input.is_open())
return false;
while(!input.eof())
{
getline(input,s);
line.clear();
Utility::String::split(line,s,' ');
if(line.size())
{
if(line[0]=="F")
{
file = line[1];
}
if(line[0]=="P")
{
ID3D10Blob *Shader,*Error;
if(!PSMap.count(line[2]))
{
PSMap[line[2]]=(int)PS.size();
ID3D11PixelShader* pixel;
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"ps_5_0",0,0,NULL,&Shader,&Error,NULL)))
{
std::string fel = (char*)Error->GetBufferPointer();
PSMap.erase(line[2]);
Error->Release();
return false;
}
if(FAILED(Oyster::Core::Device->CreatePixelShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&pixel)))
{
PSMap.erase(line[2]);
Error->Release();
Shader->Release();
return false;
}
Shader->Release();
PS.push_back(pixel);
}
}
if(line[0]=="V")
{
ID3D10Blob *Shader,*Error;
if(!VSMap.count(line[2]))
{
int i = (int)VS.size();
VSMap[line[2]]= i;
ID3D11VertexShader* vertex;
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"vs_5_0",0,0,NULL,&Shader,&Error,NULL)))
{
log //<< "Shader Compilation Warning(s)/Error(s)\n-----------------------------\n"
<< (char*) Error->GetBufferPointer();
// << "-----------------------------\n";
s = log.str();
VSMap.erase(line[2]);
Error->Release();
return false;
}
if(FAILED(Oyster::Core::Device->CreateVertexShader
(Shader->GetBufferPointer(),
Shader->GetBufferSize(),
NULL,
&vertex)))
{
VSMap.erase(line[2]);
Error->Release();
Shader->Release();
return false;
}
VS.push_back(vertex);
VBlob.push_back(Shader);
}
}
if(line[0]=="G")
{
ID3D10Blob *Shader,*Error;
if(!GSMap.count(line[2]))
{
GSMap[line[2]]=(int)GS.size();
ID3D11GeometryShader* pixel;
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"gs_5_0",0,0,NULL,&Shader,&Error,NULL)))
{
std::string fel = (char*)Error->GetBufferPointer();
GSMap.erase(line[2]);
Error->Release();
return false;
}
if(FAILED(Oyster::Core::Device->CreateGeometryShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&pixel)))
{
GSMap.erase(line[2]);
Error->Release();
Shader->Release();
return false;
}
Shader->Release();
GS.push_back(pixel);
}
}
if(line[0]=="C")
{
ID3D10Blob *Shader,*Error;
if(!CSMap.count(line[2]))
{
CSMap[line[2]]=(int)CS.size();
ID3D11ComputeShader* comp;
if(FAILED(D3DX11CompileFromFileA(file.c_str(),NULL,NULL,line[1].c_str(),"cs_5_0",0,0,NULL,&Shader,&Error,NULL)))
{
std::string fel = (char*)Error->GetBufferPointer();
CSMap.erase(line[2]);
Error->Release();
return false;
}
if(FAILED(Oyster::Core::Device->CreateComputeShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&comp)))
{
CSMap.erase(line[2]);
Error->Release();
Shader->Release();
return false;
}
Shader->Release();
CS.push_back(comp);
}
}
}
}
return true;
}
void Oyster::Shader::SetShaderEffect(ShaderEffect se)
{
Shader::Set::SetPixel(se.Shaders.Pixel);
Shader::Set::SetVertex(se.Shaders.Vertex);
Shader::Set::SetGeometry(se.Shaders.Geometry);
Shader::Set::SetCompute(se.Shaders.Compute);
Oyster::Core::DeviceContext->IASetInputLayout(se.IAStage.Layout);
Oyster::Core::DeviceContext->IASetPrimitiveTopology(se.IAStage.Topology);
for(unsigned int i=0;i<se.CBuffers.Vertex.size();++i)
se.CBuffers.Vertex[i]->Apply(i);
for(unsigned int i=0;i<se.CBuffers.Geometry.size();++i)
se.CBuffers.Geometry[i]->Apply(i);
for(unsigned int i=0;i<se.CBuffers.Pixel.size();++i)
se.CBuffers.Pixel[i]->Apply(i);
Oyster::Core::DeviceContext->RSSetState(se.RenderStates.Rasterizer);
Oyster::Core::DeviceContext->PSSetSamplers(0,se.RenderStates.SampleCount,se.RenderStates.SampleState);
float test[4] = {0};
Oyster::Core::DeviceContext->OMSetBlendState(se.RenderStates.BlendState,test,-1);
}
void Oyster::Shader::Set::SetPixel(int Index)
{
if(Index==-1)
Oyster::Core::DeviceContext->PSSetShader( NULL,NULL,0);
else
Oyster::Core::DeviceContext->PSSetShader( PS[Index],NULL,0);
}
void Oyster::Shader::Set::SetVertex(int Index)
{
if(Index==-1)
Oyster::Core::DeviceContext->VSSetShader(NULL,NULL,0);
else
Oyster::Core::DeviceContext->VSSetShader(VS[Index],NULL,0);
}
void Oyster::Shader::Set::SetGeometry(int Index)
{
if(Index==-1)
Oyster::Core::DeviceContext->GSSetShader(NULL,NULL,0);
else
Oyster::Core::DeviceContext->GSSetShader(GS[Index],NULL,0);
}
void Oyster::Shader::Set::SetCompute(int Index)
{
if(Index==-1)
Oyster::Core::DeviceContext->CSSetShader(NULL,NULL,0);
else
Oyster::Core::DeviceContext->CSSetShader(CS[Index],NULL,0);
}
void Oyster::Shader::Set::SetHull(int Index)
{
}
void Oyster::Shader::Set::SetDomain(int Index)
{
}
int Oyster::Shader::Get::GetPixel(std::string Name)
{
if(PSMap.count(Name))
return PSMap[Name];
return -1;
}
int Oyster::Shader::Get::GetVertex(std::string Name)
{
if(VSMap.count(Name))
return VSMap[Name];
return -1;
}
int Oyster::Shader::Get::GetGeometry(std::string Name)
{
if(GSMap.count(Name))
return GSMap[Name];
return -1;
}
int Oyster::Shader::Get::GetCompute(std::string Name)
{
if(CSMap.count(Name))
return CSMap[Name];
return -1;
}
int Oyster::Shader::Get::GetHull(std::string Name)
{
return -1;
}
int Oyster::Shader::Get::GetDomain(std::string Name)
{
return -1;
}
void Oyster::Shader::CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *desc, int ElementCount,int VertexIndex,ID3D11InputLayout *&Layout)
{
if(VertexIndex==-1)
{
Layout=0;
return;
}
Oyster::Core::Device->CreateInputLayout(desc,ElementCount,VBlob[VertexIndex]->GetBufferPointer(),VBlob[VertexIndex]->GetBufferSize(),&Layout);
}
}

View File

@ -0,0 +1,78 @@
#pragma once
#include "..\Core\Buffer.h"
namespace Oyster
{
class Shader
{
public:
struct ShaderEffect
{
struct
{
int Pixel,Vertex,Geometry,Compute,Hull,Domain;
}Shaders;
struct IAStage_
{
ID3D11InputLayout* Layout;
D3D11_PRIMITIVE_TOPOLOGY Topology;
}IAStage;
struct RenderStates_
{
ID3D11DepthStencilState *DepthStencil;
ID3D11RasterizerState *Rasterizer;
ID3D11SamplerState **SampleState;
int SampleCount;
ID3D11BlendState *BlendState;
}RenderStates;
struct
{
std::vector<Buffer*> Vertex;
std::vector<Buffer*> Geometry;
std::vector<Buffer*> Pixel;
}CBuffers;
ShaderEffect()
{
RenderStates.BlendState=NULL;
RenderStates.DepthStencil=NULL;
RenderStates.Rasterizer=NULL;
RenderStates.SampleState=NULL;
RenderStates.SampleCount=0;
Shaders.Compute=-1;
Shaders.Domain=-1;
Shaders.Geometry=-1;
Shaders.Hull=-1;
Shaders.Pixel=-1;
Shaders.Vertex=-1;
}
};
static bool InitShaders(const std::string &name = "..\\Shaders\\ShaderConfig.txt");
static void SetShaderEffect(ShaderEffect);
static void CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *desc, int ElementCount,int VertexIndex,ID3D11InputLayout *&Layout);
struct Set
{
static void SetPixel(int Index);
static void SetVertex(int Index);
static void SetGeometry(int Index);
static void SetCompute(int Index);
static void SetHull(int Index);
static void SetDomain(int Index);
};
struct Get
{
static int GetPixel(std::string Name);
static int GetVertex(std::string Name);
static int GetGeometry(std::string Name);
static int GetCompute(std::string Name);
static int GetHull(std::string Name);
static int GetDomain(std::string Name);
};
static std::stringstream* AccesLog();
};
}

268
OysterMath/LinearMath.h Normal file
View File

@ -0,0 +1,268 @@
/////////////////////////////////////////////////////////////////////
// Collection of Linear Math Stuff
// © Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LINEARMATH_H
#define LINEARMATH_H
#include "Vector.h"
#include "Matrix.h"
#include "Quaternion.h"
#include <math.h>
namespace LinearAlgebra
{
// x2
template<typename ElementType>
Matrix2x2<ElementType> operator * ( const Matrix2x2<ElementType> &left, const Matrix2x2<ElementType> &right )
{ return Matrix2x2<ElementType>( (left.m11 * right.m11) + (left.m21 * right.m12), (left.m11 * right.m21) + (left.m21 * right.m22), (left.m12 * right.m11) + (left.m22 * right.m12), (left.m12 * right.m21) + (left.m22 * right.m22) ); }
template<typename ElementType>
Vector2<ElementType> operator * ( const Matrix2x2<ElementType> &matrix, const Vector2<ElementType> &vector )
{ return Vector2<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) ); }
template<typename ElementType>
Vector2<ElementType> operator * ( const Vector2<ElementType> &vector, const Matrix2x2<ElementType> &left )
{ return Vector2<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12), (vector.x * matrix.m21) + (vector.y * matrix.m22) ); }
// x3
template<typename ElementType>
Matrix3x3<ElementType> operator * ( const Matrix3x3<ElementType> &left, const Matrix3x3<ElementType> &right )
{
Matrix3x3<ElementType> product, leftT = left.getTranspose();
for( int i = 0; i < 3; ++i ) for( int j = 0; j < 3; ++j )
product.m[i][j] = leftT.v[i].dot(right.v[j]);
return product;
}
template<typename ElementType>
Vector3<ElementType> operator * ( const Matrix3x3<ElementType> &matrix, const Vector3<ElementType> &vector )
{ return Vector3<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y) + (matrix.m31 * vector.z), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) + (matrix.m32 * vector.z), (matrix.m13 * vector.x) + (matrix.m23 * vector.y) + (matrix.m33 * vector.z) ); }
template<typename ElementType>
Vector3<ElementType> operator * ( const Vector3<ElementType> &vector, const Matrix3x3<ElementType> &left )
{ return Vector3<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12) + (vector.z * matrix.m13), (vector.x * matrix.m21) + (vector.y * matrix.m22) + (vector.z * matrix.m23), (vector.x * matrix.m31) + (vector.y * matrix.m32) + (vector.z * matrix.m33) ); }
// x4
template<typename ElementType>
Matrix4x4<ElementType> operator * ( const Matrix4x4<ElementType> &left, const Matrix4x4<ElementType> &right )
{
Matrix4x4<ElementType> product, rightT = right.getTranspose();
for( int i = 0; i < 4; ++i )
{
product.m[i][0] = left.v[i].dot(rightT.v[0]);
product.m[i][1] = left.v[i].dot(rightT.v[1]);
product.m[i][2] = left.v[i].dot(rightT.v[2]);
product.m[i][3] = left.v[i].dot(rightT.v[3]);
}
return product;
}
template<typename ElementType>
Vector4<ElementType> operator * ( const Matrix4x4<ElementType> &matrix, const Vector4<ElementType> &vector )
{ return Vector4<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y) + (matrix.m31 * vector.z) + (matrix.m41 * vector.w), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) + (matrix.m32 * vector.z) + (matrix.m42 * vector.w), (matrix.m13 * vector.x) + (matrix.m23 * vector.y) + (matrix.m33 * vector.z) + (matrix.m43 * vector.w), (matrix.m14 * vector.x) + (matrix.m24 * vector.y) + (matrix.m34 * vector.z) + (matrix.m44 * vector.w) ); }
template<typename ElementType> // works for column weighted matrixes
Vector4<ElementType> operator * ( const Vector4<ElementType> &vector, const Matrix4x4<ElementType> &matrix )
{ return Vector4<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12) + (vector.z * matrix.m13) + (vector.w * matrix.m14), (vector.x * matrix.m21) + (vector.y * matrix.m22) + (vector.z * matrix.m23) + (vector.w * matrix.m24), (vector.x * matrix.m31) + (vector.y * matrix.m32) + (vector.z * matrix.m33) + (vector.w * matrix.m34), (vector.x * matrix.m41) + (vector.y * matrix.m42) + (vector.z * matrix.m43) + (vector.w * matrix.m44) ); }
namespace _2D
{
template<typename ElementType>
inline void translationMatrix( Matrix3x3<ElementType> &output, const Vector2<ElementType> &position )
// { output = Matrix3x3<ElementType>( 1, 0, position.x, 0, 1, position.y, 0, 0, 1 ); }
{ output = Matrix3x3<ElementType>( 1, 0, 0, 0, 1, 0, position.x, position.y, 1 ); }
template<typename ElementType>
void rotationMatrix( Matrix2x2<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix2x2<ElementType>( c, -s, s, c );
output = Matrix2x2<ElementType>( c, s, -s, c );
}
template<typename ElementType>
void rotationMatrix( Matrix3x3<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix3x3<ElementType>( c, -s, 0, s, c, 0, 0, 0, 1 );
output = Matrix3x3<ElementType>( c, s, 0, -s, c, 0, 0, 0, 1 );
}
template<typename ElementType>
void rigidBodyMatrix( Matrix3x3<ElementType> &output, const ElementType &radian, const Vector2<ElementType> &position )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix3x3<ElementType>( c, -s, position.x, s, c, position.y, 0, 0, 1 );
output = Matrix3x3<ElementType>( c, s, 0, -s, c, 0, position.x, position.y, 1 );
}
}
namespace _3D
{
template<typename ElementType>
inline void translationMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &position )
// { output = Matrix4x4<ElementType>( 1, 0, 0, position.x, 0, 1, 0, position.y, 0, 0, 1, position.z, 0, 0, 0, 1 ); }
{ output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, position.x, position.y, position.z, 1 ); }
template<typename ElementType>
void inverseRigidBody( Matrix4x4<ElementType> &output, const Matrix4x4<ElementType> &rigidBody )
{
output = Matrix4x4<ElementType>( rigidBody.m11, rigidBody.m21, rigidBody.m31, 0,
rigidBody.m12, rigidBody.m22, rigidBody.m32, 0,
rigidBody.m13, rigidBody.m23, rigidBody.m33, 0,
-rigidBody.v[3].xyz.dot(rigidBody.v[0].xyz),
-rigidBody.v[3].xyz.dot(rigidBody.v[1].xyz),
-rigidBody.v[3].xyz.dot(rigidBody.v[2].xyz), 1 );
}
template<typename ElementType>
void rotationMatrix_AxisX( Matrix3x3<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix3x3<ElementType>( 1, 0, 0, 0, c, -s, 0, s, c );
output = Matrix3x3<ElementType>( 1, 0, 0, 0, c, s, 0, -s, c );
}
template<typename ElementType>
void rotationMatrix_AxisX( Matrix4x4<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1 );
output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1 );
}
template<typename ElementType>
void rotationMatrix_AxisY( Matrix3x3<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix3x3<ElementType>( c, 0, s, 0, 1, 0, -s, 0, c );
output = Matrix3x3<ElementType>( c, 0, -s, 0, 1, 0, s, 0, c );
}
template<typename ElementType>
void rotationMatrix_AxisY( Matrix4x4<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix4x4<ElementType>( c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1 );
output = Matrix4x4<ElementType>( c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1 );
}
template<typename ElementType>
inline void rotationMatrix_AxisZ( Matrix3x3<ElementType> &output, const ElementType &radian )
{ ::LinearAlgebra::_2D::rotationMatrix( output, radian ); }
template<typename ElementType>
void rotationMatrix_AxisZ( Matrix4x4<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix4x4<ElementType>( c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
output = Matrix4x4<ElementType>( c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
}
template<typename ElementType>
void rotationMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &normalizedAxis, const ElementType &radian )
{ // TODO : Optimize
ElementType r = radian * 0.5f,
s = std::sin( r ),
c = std::cos( r );
Quaternion<ElementType> q( normalizedAxis * s, c ),
qConj = q.getConjugate();
output.v[0] = Vector4<ElementType>( (q*Vector3<ElementType>(1,0,0)*qConj).imaginary, 0 );
output.v[1] = Vector4<ElementType>( (q*Vector3<ElementType>(0,1,0)*qConj).imaginary, 0 );
output.v[2] = Vector4<ElementType>( (q*Vector3<ElementType>(0,0,1)*qConj).imaginary, 0 );
output.v[3] = Vector4<ElementType>( 0, 0, 0, 1 );
}
/*
returns a deltaAngularAxis which is a vectorProduct of the movementVector and leverVector.
angular: (1/I) * L, there I is known as the "moment of inertia", L as the "angular momentum vector".
lever: Displacement vector relative to the rotation pivot.
Recommended reading: http://en.wikipedia.org/wiki/Torque
*/
template<typename ElementType>
inline Vector3<ElementType> deltaAngularAxis( const Vector3<ElementType> &movement, const Vector3<ElementType> &lever )
{ return movement.cross( lever ); }
template<typename ElementType>
inline Vector3<ElementType> particleRotationMovement( const Vector3<ElementType> &deltaRadian, const Vector3<ElementType> &lever )
{ return lever.cross(deltaRadian) /= lever.dot(lever); }
template<typename ElementType>
inline Vector3<ElementType> vectorProjection( const Vector3<ElementType> &vector, const Vector3<ElementType> &axis )
{ return axis * ( vector.dot(axis) / axis.dot(axis) ); }
/*
output; is set to a rigibody matrix that revolve/rotate around centerOfMass and then translates.
sumDeltaAngularAxis: Sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
sumTranslation: Sum of all the translation vectors.
centerOfMass: The point the particles is to revolve around, prior to translation. Default set to null vector aka origo.
Recommended reading: http://en.wikipedia.org/wiki/Torque
*/
template<typename ElementType>
void rigidBodyMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &sumDeltaAngularAxis, const Vector3<ElementType> &sumTranslation, const Vector3<ElementType> &centerOfMass = Vector3<ElementType>::null )
{
ElementType deltaRadian = sumDeltaAngularAxis.length();
if( deltaRadian != 0 )
{
Vector3<ElementType> axis = sumDeltaAngularAxis / deltaRadian;
rotationMatrix( output, axis, deltaRadian );
output.v[3].xyz = centerOfMass;
output.v[3].x -= centerOfMass.dot( output.v[0].xyz );
output.v[3].y -= centerOfMass.dot( output.v[1].xyz );
output.v[3].z -= centerOfMass.dot( output.v[2].xyz );
}
else output = Matrix4x4<ElementType>::identity;
output.v[3].xyz += sumTranslation;
}
/*
output; is set to an orthographic projection matrix.
width; of the projection sample volume.
height; of the projection sample volume.
nearClip: Distance to the nearClippingPlane.
farClip: Distance to the farClippingPlane
*/
template<typename ElementType>
void projectionMatrix_Orthographic( Matrix4x4<ElementType> &output, const ElementType &width, const ElementType &height, const ElementType &nearClip, const ElementType &farClip )
{
ElementType c = 1;
c /= nearClip - farClip;
output = Matrix4x4<ElementType>( 2/width, 0, 0, 0,
0, 2/height, 0, 0,
0, 0, -c, 0, 0,
0, nearClip*c, 1 );
}
/*
output; is set to a perspective transform matrix.
vertFoV; is the vertical field of vision in radians. (se FoV Hor+ )
aspect; is the screenratio width/height (example 16/9 or 16/10 )
nearClip: Distance to the nearClippingPlane
farClip: Distance to the farClippingPlane
*/
template<typename ElementType>
void projectionMatrix_Perspective( Matrix4x4<ElementType> &output, const ElementType &vertFoV, const ElementType &aspect, const ElementType &nearClip, const ElementType &farClip )
{
ElementType fov = 1 / ::std::tan( vertFoV * 0.5f ),
dDepth = farClip;
dDepth /= farClip - nearClip;
output = Matrix4x4<ElementType>( fov / aspect, 0, 0, 0, 0, fov, 0, 0, 0, 0, dDepth, 1, 0, 0, -(dDepth * nearClip), 0 );
}
}
}
#endif

761
OysterMath/Matrix.h Normal file
View File

@ -0,0 +1,761 @@
/////////////////////////////////////////////////////////////////////
// Linear Math Matrixes
// Š Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LINEARALGEBRA_MATRIX_H
#define LINEARALGEBRA_MATRIX_H
#include "Vector.h"
#include "Utilities.h"
namespace LinearAlgebra
{
template<typename ElementType>
class Matrix2x2
{
public:
union
{
ElementType m[2][2];
struct{ Vector2<ElementType> v[2]; };
// struct{ ElementType m11, m21, m12, m22; };
struct{ ElementType m11, m12, m21, m22; };
ElementType element[4];
char byte[sizeof(ElementType[4])];
};
static const Matrix2x2<ElementType> identity, null;
Matrix2x2( );
Matrix2x2( const ElementType &m11, const ElementType &m12,
const ElementType &m21, const ElementType &m22 );
Matrix2x2( const Vector2<ElementType> vec[2] );
Matrix2x2( const Vector2<ElementType> &vec1, const Vector2<ElementType> &vec2 );
Matrix2x2( const ElementType element[4] );
Matrix2x2( const Matrix2x2<ElementType> &matrix );
operator ElementType* ( );
operator const ElementType* ( ) const;
Matrix2x2<ElementType> & operator = ( const Vector2<ElementType> vec[2] );
Matrix2x2<ElementType> & operator = ( const ElementType element[4] );
Matrix2x2<ElementType> & operator = ( const Matrix2x2<ElementType> &matrix );
Matrix2x2<ElementType> & operator += ( const Matrix2x2<ElementType> &matrix );
Matrix2x2<ElementType> & operator -= ( const Matrix2x2<ElementType> &matrix );
Matrix2x2<ElementType> & operator *= ( const ElementType &scalar );
Matrix2x2<ElementType> & operator /= ( const ElementType &scalar );
Matrix2x2<ElementType> operator + ( const Matrix2x2<ElementType> &matrix ) const;
Matrix2x2<ElementType> operator - ( const Matrix2x2<ElementType> &matrix ) const;
Matrix2x2<ElementType> operator * ( const ElementType &scalar ) const;
Matrix2x2<ElementType> operator / ( const ElementType &scalar ) const;
Matrix2x2<ElementType> operator - ( ) const; // unary negation
ElementType getDeterminant( ) const;
Matrix2x2<ElementType> getAdjoint( ) const;
Matrix2x2<ElementType> getTranspose( ) const;
Matrix2x2<ElementType> & transpose( );
Matrix2x2<ElementType> getInverse( ) const;
Matrix2x2<ElementType> getInverse( ElementType &determinant ) const;
Matrix2x2<ElementType> & invert( );
Matrix2x2<ElementType> & invert( ElementType &determinant );
Vector2<ElementType> getRowVector( unsigned int rowID ) const;
const Vector2<ElementType> & getColumnVector( unsigned int colID ) const;
};
template<typename ElementType>
class Matrix3x3
{
public:
union
{
ElementType m[3][3];
struct{ Vector3<ElementType> v[3]; };
// struct{ ElementType m11, m21, m31, m12, m22, m32, m13, m23, m33; };
struct{ ElementType m11, m12, m13, m21, m22, m23, m31, m32, m33; };
ElementType element[9];
char byte[sizeof(ElementType[9])];
};
static const Matrix3x3<ElementType> identity, null;
Matrix3x3( );
Matrix3x3( const ElementType &m11, const ElementType &m12, const ElementType &m13,
const ElementType &m21, const ElementType &m22, const ElementType &m23,
const ElementType &m31, const ElementType &m32, const ElementType &m33 );
Matrix3x3( const Vector3<ElementType> vec[3] );
Matrix3x3( const Vector3<ElementType> &vec1, const Vector3<ElementType> &vec2, const Vector3<ElementType> &vec3 );
Matrix3x3( const ElementType element[9] );
Matrix3x3( const Matrix3x3<ElementType> &matrix );
operator ElementType* ( );
operator const ElementType* ( ) const;
Matrix3x3<ElementType> & operator = ( const Vector3<ElementType> vec[3] );
Matrix3x3<ElementType> & operator = ( const ElementType element[9] );
Matrix3x3<ElementType> & operator = ( const Matrix3x3<ElementType> &matrix );
Matrix3x3<ElementType> & operator += ( const Matrix3x3<ElementType> &matrix );
Matrix3x3<ElementType> & operator -= ( const Matrix3x3<ElementType> &matrix );
Matrix3x3<ElementType> & operator *= ( const ElementType &scalar );
Matrix3x3<ElementType> & operator /= ( const ElementType &scalar );
Matrix3x3<ElementType> operator + ( const Matrix3x3<ElementType> &matrix ) const;
Matrix3x3<ElementType> operator - ( const Matrix3x3<ElementType> &matrix ) const;
Matrix3x3<ElementType> operator * ( const ElementType &scalar ) const;
Matrix3x3<ElementType> operator / ( const ElementType &scalar ) const;
Matrix3x3<ElementType> operator - ( ) const; // unary negation
ElementType getDeterminant( ) const;
Matrix3x3<ElementType> getAdjoint( ) const;
Matrix3x3<ElementType> getTranspose( ) const;
Matrix3x3<ElementType> & transpose( );
Matrix3x3<ElementType> getInverse( ) const;
Matrix3x3<ElementType> getInverse( ElementType &determinant ) const;
Matrix3x3<ElementType> & invert( );
Matrix3x3<ElementType> & invert( ElementType &determinant );
Vector3<ElementType> getRowVector( unsigned int rowID ) const;
const Vector3<ElementType> & getColumnVector( unsigned int colID ) const;
};
template<typename ElementType>
class Matrix4x4
{
public:
union
{
ElementType m[4][4];
struct{ Vector4<ElementType> v[4]; };
// struct{ ElementType m11, m21, m31, m41, m12, m22, m32, m42, m13, m23, m33, m43, m14, m24, m34, m44; };
struct{ ElementType m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; };
ElementType element[16];
char byte[sizeof(ElementType[16])];
};
static const Matrix4x4<ElementType> identity, null;
Matrix4x4( );
Matrix4x4( const ElementType &m11, const ElementType &m12, const ElementType &m13, const ElementType &m14,
const ElementType &m21, const ElementType &m22, const ElementType &m23, const ElementType &m24,
const ElementType &m31, const ElementType &m32, const ElementType &m33, const ElementType &m34,
const ElementType &m41, const ElementType &m42, const ElementType &m43, const ElementType &m44 );
Matrix4x4( const Vector4<ElementType> vec[4] );
Matrix4x4( const Vector4<ElementType> &vec1, const Vector4<ElementType> &vec2, const Vector4<ElementType> &vec3, const Vector4<ElementType> &vec4 );
Matrix4x4( const ElementType element[16] );
Matrix4x4( const Matrix4x4<ElementType> &matrix );
operator ElementType* ( );
operator const ElementType* ( ) const;
Matrix4x4<ElementType> & operator = ( const Vector4<ElementType> vec[4] );
Matrix4x4<ElementType> & operator = ( const ElementType element[16] );
Matrix4x4<ElementType> & operator = ( const Matrix4x4<ElementType> &matrix );
Matrix4x4<ElementType> & operator += ( const Matrix4x4<ElementType> &matrix );
Matrix4x4<ElementType> & operator -= ( const Matrix4x4<ElementType> &matrix );
Matrix4x4<ElementType> & operator *= ( const ElementType &scalar );
Matrix4x4<ElementType> & operator /= ( const ElementType &scalar );
Matrix4x4<ElementType> operator + ( const Matrix4x4<ElementType> &matrix ) const;
Matrix4x4<ElementType> operator - ( const Matrix4x4<ElementType> &matrix ) const;
Matrix4x4<ElementType> operator * ( const ElementType &scalar ) const;
Matrix4x4<ElementType> operator / ( const ElementType &scalar ) const;
Matrix4x4<ElementType> operator - ( ) const; // unary negation
ElementType getDeterminant( ) const;
Matrix4x4<ElementType> getAdjoint( ) const;
Matrix4x4<ElementType> getTranspose( ) const;
Matrix4x4<ElementType> & transpose( );
Matrix4x4<ElementType> getInverse( ) const;
Matrix4x4<ElementType> getInverse( ElementType &determinant ) const;
Matrix4x4<ElementType> & invert( );
Matrix4x4<ElementType> & invert( ElementType &determinant );
Vector4<ElementType> getRowVector( unsigned int rowID ) const;
const Vector4<ElementType> & getColumnVector( unsigned int colID ) const;
};
///////////////////////////////////////////////////////////////////////////////////
// Body
///////////////////////////////////////////////////////////////////////////////////
// Matrix2x2<ElementType> ///////////////////////////////////////
template<typename ElementType>
const Matrix2x2<ElementType> Matrix2x2<ElementType>::identity = Matrix2x2<ElementType>( 1, 0, 0, 1 );
template<typename ElementType>
const Matrix2x2<ElementType> Matrix2x2<ElementType>::null = Matrix2x2<ElementType>( 0, 0, 0, 0 );
template<typename ElementType>
Matrix2x2<ElementType>::Matrix2x2( ) : m11(0), m21(0), m12(0), m22(0) {}
template<typename ElementType>
Matrix2x2<ElementType>::Matrix2x2( const ElementType &_m11, const ElementType &_m12, const ElementType &_m21, const ElementType &_m22 )
: m11(_m11), m21(_m21), m12(_m12), m22(_m22) {}
template<typename ElementType>
Matrix2x2<ElementType>::Matrix2x2( const Vector2<ElementType> vec[2] )
: m11(vec[0].x), m21(vec[0].y), m12(vec[1].x), m22(vec[1].y) {}
template<typename ElementType>
Matrix2x2<ElementType>::Matrix2x2( const Vector2<ElementType> &vec1, const Vector2<ElementType> &vec2 )
: m11(vec1.x), m21(vec1.y), m12(vec2.x), m22(vec2.y) {}
template<typename ElementType>
Matrix2x2<ElementType>::Matrix2x2( const ElementType _element[4] )
// : m11(_element[0]), m21(_element[1]), m12(_element[2]), m22(_element[3]) {}
: m11(_element[0]), m12(_element[1]), m21(_element[2]), m22(_element[3]) {}
template<typename ElementType>
Matrix2x2<ElementType>::Matrix2x2( const Matrix2x2<ElementType> &matrix )
: m11(matrix.m11), m21(matrix.m12), m12(matrix.m21), m22(matrix.m22) {}
template<typename ElementType>
inline Matrix2x2<ElementType>::operator ElementType* ( )
{ return this->element; }
template<typename ElementType>
inline Matrix2x2<ElementType>::operator const ElementType* ( ) const
{ return this->element; }
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator = ( const Vector2<ElementType> vec[2] )
{
this->v[0] = vec[0];
this->v[1] = vec[1];
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator = ( const ElementType element[4] )
{
for( int i = 0; i < 4; ++i )
this->element[i] = element[i];
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator = ( const Matrix2x2<ElementType> &matrix )
{
this->v[0] = matrix.v[0];
this->v[1] = matrix.v[1];
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator += ( const Matrix2x2<ElementType> &matrix )
{
this->v[0] += matrix.v[0];
this->v[1] += matrix.v[1];
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator -= ( const Matrix2x2<ElementType> &matrix )
{
this->v[0] -= matrix.v[0];
this->v[1] -= matrix.v[1];
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator *= ( const ElementType &scalar )
{
this->v[0] *= scalar;
this->v[1] *= scalar;
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::operator /= ( const ElementType &scalar )
{
this->v[0] /= scalar;
this->v[1] /= scalar;
return *this;
}
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator + ( const Matrix2x2<ElementType> &matrix ) const
{ return Matrix2x2<ElementType>(*this) += matrix; }
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator - ( const Matrix2x2<ElementType> &matrix ) const
{ return Matrix2x2<ElementType>(*this) -= matrix; }
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator * ( const ElementType &scalar ) const
{ return Matrix2x2<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator / ( const ElementType &scalar ) const
{ return Matrix2x2<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::operator - ( ) const
{ return Matrix2x2<ElementType>(-this->v[0], -this->v[1]); }
template<typename ElementType>
ElementType Matrix2x2<ElementType>::getDeterminant( ) const
{
ElementType determinant = (this->m11 * this->m22);
return determinant -= (this->m12 * this->m21);
}
template<typename ElementType>
Matrix2x2<ElementType> Matrix2x2<ElementType>::getAdjoint( ) const
{ return Matrix2x2<ElementType>( this->m22, -this->m21, -this->m12, this->m11 ); }
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::getTranspose( ) const
{ return Matrix2x2<ElementType>( this->element[0], this->element[1], this->element[2], this->element[3] ); }
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::transpose( )
{
ElementType swapSpace;
Utility::Element::swap( this->m12, this->m21, swapSpace );
return *this;
}
template<typename ElementType>
inline Matrix2x2<ElementType> Matrix2x2<ElementType>::getInverse( ) const
{ return this->getAdjoint() /= this->getDeterminant(); }
template<typename ElementType>
Matrix2x2<ElementType> Matrix2x2<ElementType>::getInverse( ElementType &determinant ) const
{
determinant = this->getDeterminant();
if( determinant != 0 )
return this->getAdjoint() / determinant;
return Matrix2x2<ElementType>();
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::invert( )
{
*this /= this->getDeterminant();
this->m12 *= -1; this->m21 *= -1;
ElementType swapSpace;
Utility::Element::swap( this->m12, this->m21, swapSpace );
Utility::Element::swap( this->m11, this->m22, swapSpace );
return *this;
}
template<typename ElementType>
Matrix2x2<ElementType> & Matrix2x2<ElementType>::invert( ElementType &determinant )
{
determinant = this->getDeterminant();
if( determinant != 0 )
{
*this /= determinant;
this->m12 *= -1; this->m21 *= -1;
ElementType swapSpace;
Utility::Element::swap( this->m12, this->m21, swapSpace );
Utility::Element::swap( this->m11, this->m22, swapSpace );
}
return *this;
}
template<typename ElementType>
inline Vector2<ElementType> Matrix2x2<ElementType>::getRowVector( unsigned int rowID ) const
{ return Vector2<ElementType>( this->m[0][rowID], this->m[1][rowID] ); }
template<typename ElementType>
inline const Vector2<ElementType> & Matrix2x2<ElementType>::getColumnVector( unsigned int colID ) const
{ return this->v[colID]; }
// Matrix3x3<ElementType> ///////////////////////////////////////
template<typename ElementType>
const Matrix3x3<ElementType> Matrix3x3<ElementType>::identity = Matrix3x3<ElementType>( 1, 0, 0, 0, 1, 0, 0, 0, 1 );
template<typename ElementType>
const Matrix3x3<ElementType> Matrix3x3<ElementType>::null = Matrix3x3<ElementType>( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
template<typename ElementType>
Matrix3x3<ElementType>::Matrix3x3( ) : m11(0), m21(0), m31(0), m12(0), m22(0), m32(0), m13(0), m23(0), m33(0) {}
template<typename ElementType>
Matrix3x3<ElementType>::Matrix3x3( const ElementType &_m11, const ElementType &_m12, const ElementType &_m13, const ElementType &_m21, const ElementType &_m22, const ElementType &_m23, const ElementType &_m31, const ElementType &_m32, const ElementType &_m33 )
: m11(_m11), m21(_m21), m31(_m31), m12(_m12), m22(_m22), m32(_m32), m13(_m13), m23(_m23), m33(_m33) {}
template<typename ElementType>
Matrix3x3<ElementType>::Matrix3x3( const Vector3<ElementType> vec[3] )
: m11(vec[0].x), m21(vec[0].y), m31(vec[0].z), m12(vec[1].x), m22(vec[1].y), m32(vec[1].z), m13(vec[2].x), m23(vec[2].y), m33(vec[2].z) {}
template<typename ElementType>
Matrix3x3<ElementType>::Matrix3x3( const Vector3<ElementType> &vec1, const Vector3<ElementType> &vec2, const Vector3<ElementType> &vec3 )
: m11(vec1.x), m21(vec1.y), m31(vec1.z), m12(vec2.x), m22(vec2.y), m32(vec2.z), m13(vec3.x), m23(vec3.y), m33(vec3.z) {}
template<typename ElementType>
Matrix3x3<ElementType>::Matrix3x3( const ElementType _element[9] )
// : m11(_element[0]), m21(_element[1]), m31(_element[2]), m12(_element[3]), m22(_element[4]), m32(_element[5]), m13(_element[6]), m23(_element[7]), m33(_element[8]) {}
: m11(_element[0]), m12(_element[1]), m13(_element[2]), m21(_element[3]), m22(_element[4]), m23(_element[5]), m31(_element[6]), m32(_element[7]), m33(_element[8]) {}
template<typename ElementType>
Matrix3x3<ElementType>::Matrix3x3( const Matrix3x3<ElementType> &matrix )
: m11(matrix.m11), m21(matrix.m21), m31(matrix.m31), m12(matrix.m12), m22(matrix.m22), m32(matrix.m32), m13(matrix.m13), m23(matrix.m23), m33(matrix.m33) {}
template<typename ElementType>
inline Matrix3x3<ElementType>::operator ElementType* ( )
{ return this->element; }
template<typename ElementType>
inline Matrix3x3<ElementType>::operator const ElementType* ( ) const
{ return this->element; }
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator = ( const Vector3<ElementType> vec[3] )
{
this->v[0] = vec[0];
this->v[1] = vec[1];
this->v[2] = vec[2];
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator = ( const ElementType element[9] )
{
for( int i = 0; i < 9; ++i )
this->element[i] = element[i];
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator = ( const Matrix3x3<ElementType> &matrix )
{
this->v[0] = matrix.v[0];
this->v[1] = matrix.v[1];
this->v[2] = matrix.v[2];
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator += ( const Matrix3x3<ElementType> &matrix )
{
this->v[0] += matrix.v[0];
this->v[1] += matrix.v[1];
this->v[2] += matrix.v[2];
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator -= ( const Matrix3x3<ElementType> &matrix )
{
this->v[0] -= matrix.v[0];
this->v[1] -= matrix.v[1];
this->v[2] -= matrix.v[2];
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator *= ( const ElementType &scalar )
{
this->v[0] *= scalar;
this->v[1] *= scalar;
this->v[2] *= scalar;
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::operator /= ( const ElementType &scalar )
{
this->v[0] /= scalar;
this->v[1] /= scalar;
this->v[2] /= scalar;
return *this;
}
template<typename ElementType>
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator + ( const Matrix3x3<ElementType> &matrix ) const
{ return Matrix3x3<ElementType>(*this) += matrix; }
template<typename ElementType>
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator - ( const Matrix3x3<ElementType> &matrix ) const
{ return Matrix3x3<ElementType>(*this) -= matrix; }
template<typename ElementType>
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator * ( const ElementType &scalar ) const
{ return Matrix3x3<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator / ( const ElementType &scalar ) const
{ return Matrix3x3<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::operator - ( ) const
{ return Matrix3x3<ElementType>(-this->v[0], -this->v[1], -this->v[2]); }
template<typename ElementType>
ElementType Matrix3x3<ElementType>::getDeterminant( ) const
{
ElementType determinant = (this->m11 * this->m22 * this->m33);
determinant += (this->m12 * this->m23 * this->m31);
determinant += (this->m13 * this->m21 * this->m32);
determinant -= (this->m11 * this->m23 * this->m32);
determinant -= (this->m12 * this->m21 * this->m33);
return determinant -= (this->m13 * this->m22 * this->m31);
}
template<typename ElementType>
Matrix3x3<ElementType> Matrix3x3<ElementType>::getAdjoint( ) const
{
return Matrix3x3<ElementType>( (this->m22*this->m33 - this->m23*this->m32), (this->m13*this->m32 - this->m12*this->m33), (this->m12*this->m23 - this->m13*this->m22),
(this->m23*this->m31 - this->m21*this->m33), (this->m11*this->m33 - this->m13*this->m31), (this->m13*this->m21 - this->m11*this->m23),
(this->m21*this->m32 - this->m22*this->m31), (this->m12*this->m31 - this->m11*this->m32), (this->m11*this->m22 - this->m12*this->m21) );
}
template<typename ElementType>
inline Matrix3x3<ElementType> Matrix3x3<ElementType>::getTranspose( ) const
{
return Matrix3x3<ElementType>( this->m11, this->m21, this->m31,
this->m12, this->m22, this->m32,
this->m13, this->m23, this->m33 );
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::transpose( )
{
ElementType swapSpace;
Utility::Element::swap( this->m12, this->m21, swapSpace );
Utility::Element::swap( this->m13, this->m31, swapSpace );
Utility::Element::swap( this->m23, this->m32, swapSpace );
return *this;
}
template<typename ElementType>
Matrix3x3<ElementType> Matrix3x3<ElementType>::getInverse( ) const
{ return this->getAdjoint() /= this->getDeterminant(); }
template<typename ElementType>
Matrix3x3<ElementType> Matrix3x3<ElementType>::getInverse( ElementType &determinant ) const
{
determinant = this->getDeterminant();
if( determinant != 0 )
return this->getAdjoint() /= determinant;
else return Matrix3x3<ElementType>();
}
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::invert( )
{ return *this = this->getAdjoint() /= this->getDeterminant(); }
template<typename ElementType>
Matrix3x3<ElementType> & Matrix3x3<ElementType>::invert( ElementType &determinant )
{
determinant = this->getDeterminant();
if( determinant != 0 )
return *this = this->getAdjoint() /= determinant;
return *this;
}
template<typename ElementType>
inline Vector3<ElementType> Matrix3x3<ElementType>::getRowVector( unsigned int rowID ) const
{ return Vector3<ElementType>( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID] ); }
template<typename ElementType>
inline const Vector3<ElementType> & Matrix3x3<ElementType>::getColumnVector( unsigned int colID ) const
{ return this->v[colID]; }
// Matrix4x4<ElementType> ///////////////////////////////////////
template<typename ElementType>
const Matrix4x4<ElementType> Matrix4x4<ElementType>::identity = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
template<typename ElementType>
const Matrix4x4<ElementType> Matrix4x4<ElementType>::null = Matrix4x4<ElementType>( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
template<typename ElementType>
Matrix4x4<ElementType>::Matrix4x4( )
: m11(0), m21(0), m31(0), m41(0), m12(0), m22(0), m32(0), m42(0), m13(0), m23(0), m33(0), m43(0), m14(0), m24(0), m34(0), m44(0) {}
template<typename ElementType>
Matrix4x4<ElementType>::Matrix4x4( const ElementType &_m11, const ElementType &_m12, const ElementType &_m13, const ElementType &_m14, const ElementType &_m21, const ElementType &_m22, const ElementType &_m23, const ElementType &_m24, const ElementType &_m31, const ElementType &_m32, const ElementType &_m33, const ElementType &_m34, const ElementType &_m41, const ElementType &_m42, const ElementType &_m43, const ElementType &_m44 )
: m11(_m11), m21(_m21), m31(_m31), m41(_m41), m12(_m12), m22(_m22), m32(_m32), m42(_m42), m13(_m13), m23(_m23), m33(_m33), m43(_m43), m14(_m14), m24(_m24), m34(_m34), m44(_m44) {}
template<typename ElementType>
Matrix4x4<ElementType>::Matrix4x4( const Vector4<ElementType> vec[4] )
: m11(vec[0].x), m21(vec[0].y), m31(vec[0].z), m41(vec[0].w), m12(vec[1].x), m22(vec[1].y), m32(vec[1].z), m42(vec[1].w), m13(vec[2].x), m23(vec[2].y), m33(vec[2].z), m43(vec[2].w), m14(vec[3].x), m24(vec[3].y), m34(vec[3].z), m44(vec[3].w) {}
template<typename ElementType>
Matrix4x4<ElementType>::Matrix4x4( const Vector4<ElementType> &vec1, const Vector4<ElementType> &vec2, const Vector4<ElementType> &vec3, const Vector4<ElementType> &vec4 )
: m11(vec1.x), m21(vec1.y), m31(vec1.z), m41(vec1.w), m12(vec2.x), m22(vec2.y), m32(vec2.z), m42(vec2.w), m13(vec3.x), m23(vec3.y), m33(vec3.z), m43(vec3.w), m14(vec4.x), m24(vec4.y), m34(vec4.z), m44(vec4.w) {}
template<typename ElementType>
Matrix4x4<ElementType>::Matrix4x4( const ElementType _element[16] )
// : m11(_element[0]), m21(_element[1]), m31(_element[2]), m41(_element[3]), m12(_element[4]), m22(_element[5]), m32(_element[6]), m42(_element[7]), m13(_element[8]), m23(_element[9]), m33(_element[10]), m43(_element[11]), m14(_element[12]), m24(_element[13]), m34(_element[14]), m44(_element[15]) {}
: m11(_element[0]), m12(_element[1]), m13(_element[2]), m14(_element[3]), m21(_element[4]), m22(_element[5]), m23(_element[6]), m24(_element[7]), m31(_element[8]), m32(_element[9]), m33(_element[10]), m34(_element[11]), m41(_element[12]), m42(_element[13]), m43(_element[14]), m44(_element[15]) {}
template<typename ElementType>
Matrix4x4<ElementType>::Matrix4x4( const Matrix4x4<ElementType> &matrix )
: m11(matrix.m11), m21(matrix.m21), m31(matrix.m31), m41(matrix.m41), m12(matrix.m12), m22(matrix.m22), m32(matrix.m32), m42(matrix.m42), m13(matrix.m13), m23(matrix.m23), m33(matrix.m33), m43(matrix.m43), m14(matrix.m14), m24(matrix.m24), m34(matrix.m34), m44(matrix.m44) {}
template<typename ElementType>
inline Matrix4x4<ElementType>::operator ElementType* ( )
{ return this->element; }
template<typename ElementType>
inline Matrix4x4<ElementType>::operator const ElementType* ( ) const
{ return this->element; }
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator = ( const Vector4<ElementType> vec[4] )
{
this->v[0] = vec[0];
this->v[1] = vec[1];
this->v[2] = vec[2];
this->v[3] = vec[3];
return *this;
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator = ( const ElementType element[16] )
{
for( int i = 0; i < 16; ++i )
this->element[i] = element[i];
return *this;
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator = ( const Matrix4x4<ElementType> &matrix )
{
this->v[0] = matrix.v[0];
this->v[1] = matrix.v[1];
this->v[2] = matrix.v[2];
this->v[3] = matrix.v[3];
return *this;
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator += ( const Matrix4x4<ElementType> &matrix )
{
this->v[0] += matrix.v[0];
this->v[1] += matrix.v[1];
this->v[2] += matrix.v[2];
this->v[3] += matrix.v[3];
return *this;
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator -= ( const Matrix4x4<ElementType> &matrix )
{
this->v[0] -= matrix.v[0];
this->v[1] -= matrix.v[1];
this->v[2] -= matrix.v[2];
this->v[3] -= matrix.v[3];
return *this;
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator *= ( const ElementType &scalar )
{
this->v[0] *= scalar;
this->v[1] *= scalar;
this->v[2] *= scalar;
this->v[3] *= scalar;
return *this;
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::operator /= ( const ElementType &scalar )
{
this->v[0] /= scalar;
this->v[1] /= scalar;
this->v[2] /= scalar;
this->v[3] /= scalar;
return *this;
}
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator + ( const Matrix4x4<ElementType> &matrix ) const
{ return Matrix4x4<ElementType>(*this) += matrix; }
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator - ( const Matrix4x4<ElementType> &matrix ) const
{ return Matrix4x4<ElementType>(*this) -= matrix; }
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator * ( const ElementType &scalar ) const
{ return Matrix4x4<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator / ( const ElementType &scalar ) const
{ return Matrix4x4<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::operator - ( ) const
{ return Matrix4x4<ElementType>(-this->v[0], -this->v[1], -this->v[2], -this->v[3]); }
template<typename ElementType>
ElementType Matrix4x4<ElementType>::getDeterminant( ) const
{
ElementType determinant = this->m11 * Matrix3x3<ElementType>(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).getDeterminant();
determinant -= this->m12 * Matrix3x3<ElementType>(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).getDeterminant();
determinant += this->m13 * Matrix3x3<ElementType>(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).getDeterminant();
return determinant -= this->m14 * Matrix3x3<ElementType>(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).getDeterminant();
}
template<typename ElementType>
Matrix4x4<ElementType> Matrix4x4<ElementType>::getAdjoint( ) const
{
return Matrix4x4<ElementType>( Matrix3x3<ElementType>(this->m22, this->m23, this->m24, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m12, this->m13, this->m14, this->m32, this->m33, this->m34, this->m42, this->m43, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m42, this->m43, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m12, this->m13, this->m14, this->m22, this->m23, this->m24, this->m32, this->m33, this->m34).getDeterminant(),
-Matrix3x3<ElementType>(this->m21, this->m23, this->m24, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m13, this->m14, this->m31, this->m33, this->m34, this->m41, this->m43, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m41, this->m43, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m13, this->m14, this->m21, this->m23, this->m24, this->m31, this->m33, this->m34).getDeterminant(),
Matrix3x3<ElementType>(this->m21, this->m22, this->m24, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m12, this->m14, this->m31, this->m32, this->m34, this->m41, this->m42, this->m44).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m41, this->m42, this->m44).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m12, this->m14, this->m21, this->m22, this->m24, this->m31, this->m32, this->m34).getDeterminant(),
-Matrix3x3<ElementType>(this->m21, this->m22, this->m23, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m12, this->m13, this->m31, this->m32, this->m33, this->m41, this->m42, this->m43).getDeterminant(), -Matrix3x3<ElementType>(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m41, this->m42, this->m43).getDeterminant(), Matrix3x3<ElementType>(this->m11, this->m12, this->m13, this->m21, this->m22, this->m23, this->m31, this->m32, this->m33).getDeterminant() );
}
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::getTranspose( ) const
{
return Matrix4x4<ElementType>( this->m11, this->m21, this->m31, this->m41,
this->m12, this->m22, this->m32, this->m42,
this->m13, this->m23, this->m33, this->m43,
this->m14, this->m24, this->m34, this->m44 );
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::transpose( )
{
ElementType swapSpace;
::Utility::Element::swap( this->m12, this->m21, swapSpace );
::Utility::Element::swap( this->m13, this->m31, swapSpace );
::Utility::Element::swap( this->m14, this->m41, swapSpace );
::Utility::Element::swap( this->m23, this->m32, swapSpace );
::Utility::Element::swap( this->m24, this->m42, swapSpace );
::Utility::Element::swap( this->m34, this->m43, swapSpace );
return *this;
}
template<typename ElementType>
inline Matrix4x4<ElementType> Matrix4x4<ElementType>::getInverse( ) const
{ return this->getAdjoint() /= this->getDeterminant() ; }
template<typename ElementType>
Matrix4x4<ElementType> Matrix4x4<ElementType>::getInverse( ElementType &determinant ) const
{
determinant = this->getDeterminant();
if( determinant != 0.0f )
return this->getAdjoint() /= determinant;
return Matrix4x4<ElementType>();
}
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::invert( )
{ return *this = this->getAdjoint() /= this->getDeterminant(); }
template<typename ElementType>
Matrix4x4<ElementType> & Matrix4x4<ElementType>::invert( ElementType &determinant )
{
determinant = this->getDeterminant();
if( determinant != 0.0f )
return *this = this->getAdjoint() /= determinant;
return *this;
}
template<typename ElementType>
inline Vector4<ElementType> Matrix4x4<ElementType>::getRowVector( unsigned int rowID ) const
{ return Vector4<ElementType>( this->m[0][rowID], this->m[1][rowID], this->m[2][rowID], this->m[3][rowID] ); }
template<typename ElementType>
inline const Vector4<ElementType> & Matrix4x4<ElementType>::getColumnVector( unsigned int colID ) const
{ return this->v[colID]; }
}
#endif

32
OysterMath/OysterMath.cpp Normal file
View File

@ -0,0 +1,32 @@
/////////////////////////////////////////////////////////////////////
// by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#include "OysterMath.h"
namespace Oyster { namespace Math
{
Float2 & operator *= ( Float2 &left, const Float2 &right )
{
left.x *= right.x;
left.y *= right.y;
return left;
}
Float3 & operator *= ( Float3 &left, const Float3 &right )
{
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
return left;
}
Float4 & operator *= ( Float4 &left, const Float4 &right )
{
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
left.w *= right.w;
return left;
}
} }

220
OysterMath/OysterMath.h Normal file
View File

@ -0,0 +1,220 @@
/////////////////////////////////////////////////////////////////////
// by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_MATH_H
#define OYSTER_MATH_H
#include "Utilities.h"
#include "LinearMath.h"
#include <limits>
namespace Oyster { namespace Math
{
typedef float Float;
typedef ::LinearAlgebra::Vector2<Float> Float2;
typedef ::LinearAlgebra::Vector3<Float> Float3;
typedef ::LinearAlgebra::Vector4<Float> Float4;
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2;
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3;
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4;
typedef Float4x4 Matrix;
typedef Float2 Vector2;
typedef Float3 Vector3;
typedef Float4 Vector4;
Float2 & operator *= ( Float2 &left, const Float2 &right );
inline Float2 operator * ( const Float2 &left, const Float2 &right )
{ return Float2(left) *= right; }
inline Float2 operator * ( const Float &left, const Float2 &right )
{ return Float2(right) *= left; }
Float3 & operator *= ( Float3 &left, const Float3 &right );
inline Float3 operator * ( const Float3 &left, const Float3 &right )
{ return Float3(left) *= right; }
inline Float3 operator * ( const Float &left, const Float3 &right )
{ return Float3(right) *= left; }
Float4 & operator *= ( Float4 &left, const Float4 &right );
inline Float4 operator * ( const Float4 &left, const Float4 &right )
{ return Float4(left) *= right; }
inline Float4 operator * ( const Float &left, const Float4 &right )
{ return Float4(right) *= left; }
inline Float2x2 operator * ( const Float &left, const Float2x2 &right )
{ return Float2x2(right) *= left; }
inline Float3x3 operator * ( const Float &left, const Float3x3 &right )
{ return Float3x3(right) *= left; }
inline Float4x4 operator * ( const Float &left, const Float4x4 &right )
{ return Float4x4(right) *= left; }
// Deprecated function! Use the static const member identity instead.
inline void identityMatrix( Float2x2 &output )
{ output = Float2x2::identity; }
// Deprecated function! Use the static const member identity instead.
inline void identityMatrix( Float3x3 &output )
{ output = Float3x3::identity; }
// Deprecated function! Use the static const member identity instead.
inline void identityMatrix( Float4x4 &output )
{ output = Float4x4::identity; }
// If rigidBody is assumed to be by all definitions a rigid body matrix. Then this is a faster inverse method.
inline void inverseRigidBodyMatrix( Float4x4 &output, const Float4x4 &rigidBody )
{ ::LinearAlgebra::_3D::inverseRigidBody( output, rigidBody ); }
inline void translationMatrix( Float4x4 &output, const Float3 &position )
{ ::LinearAlgebra::_3D::translationMatrix( output, position ); }
// counterclockwise rotation around X axis
inline void rotationMatrix_AxisX( Float4x4 &output, const Float &radian )
{ ::LinearAlgebra::_3D::rotationMatrix_AxisX( output, radian ); }
// counterclockwise rotation around Y axis
inline void rotationMatrix_AxisY( Float4x4 &output, const Float &radian )
{ ::LinearAlgebra::_3D::rotationMatrix_AxisY( output, radian ); }
// counterclockwise rotation around Z axis
inline void rotationMatrix_AxisZ( Float4x4 &output, const Float &radian )
{ ::LinearAlgebra::_3D::rotationMatrix_AxisZ( output, radian ); }
// counterclockwise rotation around any given Float3 vector (normalizedAxis). Please make sure it is normalized.
inline void rotationMatrix( Float4x4 &output, const Float &radian, const Float3 &normalizedAxis )
{ ::LinearAlgebra::_3D::rotationMatrix( output, normalizedAxis, radian ); }
/*
returns a deltaAngularAxis which is a vectorProduct of the particleMovementVector and leverVector.
angular: (1/I) * L, there I is known as the "moment of inertia", L as the "angular momentum vector".
lever: Displacement vector relative to the center of mass.
Recommended reading: http://en.wikipedia.org/wiki/Torque
*/
inline Float3 deltaAngularAxis( const Float3 &movement, const Float3 &lever )
{ return ::LinearAlgebra::_3D::deltaAngularAxis( movement, lever ); }
inline Float3 particleRotationMovement( const Float3 &deltaRadian, const Float3 &lever )
{ return ::LinearAlgebra::_3D::particleRotationMovement( deltaRadian, lever ); }
inline Float3 vectorProjection( const Float3 &vector, const Float3 &axis )
{ return ::LinearAlgebra::_3D::vectorProjection( vector, axis ); }
/*
output: is set to a rigibody matrix that revolve/rotate around centerOfMass and then translates.
sumDeltaAngularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
sumTranslation: sum of all the translation vectors.
centerOfMass: the point the particles is to revolve around, prior to translation. Default set to null vector aka origo.
Recommended reading: http://en.wikipedia.org/wiki/Torque
*/
inline void rigidBodyMatrix( Float4x4 &output, const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 &centerOfMass = Float3::null )
{ ::LinearAlgebra::_3D::rigidBodyMatrix( output, sumDeltaAngularAxis, sumTranslation, centerOfMass ); }
/*
output; is set to an orthographic projection matrix.
width; of the projection sample volume.
height; of the projection sample volume.
near: Distance to the nearPlane.
far: Distance to the farPlane
*/
inline void projectionMatrix_Orthographic( Float4x4 &output, const Float &width, const Float &height, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max() )
{ ::LinearAlgebra::_3D::projectionMatrix_Orthographic( output, width, height, nearClip, farClip ); }
/*
output; is set to a perspective transform matrix.
vertFoV; is the vertical field of vision in radians. (se FoV Hor+ )
aspect; is the screenratio width/height (example 16/9 or 16/10 )
near: Distance to the nearPlane
far: Distance to the farPlane
*/
inline void projectionMatrix_Perspective( Float4x4 &output, const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max() )
{ ::LinearAlgebra::_3D::projectionMatrix_Perspective( output, verticalFoV, aspectRatio, nearClip, farClip ); }
inline Float4x4 & viewProjectionMatrix( Float4x4 &output, const Float4x4 &view, const Float4x4 &projection )
{ return output = (view * projection).getTranspose(); }
inline Float4x4 & transformMatrix( Float4x4 &output, const Float4x4 &transformee, const Float4x4 &transformer )
{ return output = transformee * transformer; }
inline Float4x4 transformMatrix( const Float4x4 &transformee, const Float4x4 &transformer )
{ return transformee * transformer; }
inline Float4 & transformVector( Float4 &output, const Float4 &transformee, const Float4x4 &transformer )
{ return output = transformer * transformee; }
inline Float4 transformVector( const Float4 &transformee, const Float4x4 &transformer )
{ return transformee * transformer; }
} }
namespace Utility { namespace Value
{ // Utility Value Specializations
using namespace ::Oyster::Math;
template< > inline Float2 abs<Float2>( const Float2 &value )
{ return Float2( abs(value.x), abs(value.y) ); }
template< > inline Float2 max<Float2>( const Float2 &valueA, const Float2 &valueB )
{ return Float2( max(valueA.x, valueB.x), max(valueA.y, valueB.y) ); }
template< > inline Float2 min<Float2>( const Float2 &valueA, const Float2 &valueB )
{ return Float2( min(valueA.x, valueB.x), min(valueA.y, valueB.y) ); }
template< > inline Float3 abs<Float3>( const Float3 &value )
{ return Float3( abs(value.xy), abs(value.z) ); }
template< > inline Float3 max<Float3>( const Float3 &valueA, const Float3 &valueB )
{ return Float3( max(valueA.xy, valueB.xy), max(valueA.z, valueB.z) ); }
template< > inline Float3 min<Float3>( const Float3 &valueA, const Float3 &valueB )
{ return Float3( min(valueA.xy, valueB.xy), min(valueA.z, valueB.z) ); }
template< > inline Float4 abs<Float4>( const Float4 &value )
{ return Float4( abs(value.xyz), abs(value.w) ); }
template< > inline Float4 max<Float4>( const Float4 &valueA, const Float4 &valueB )
{ return Float4( max(valueA.xyz, valueB.xyz), max(valueA.w, valueB.w) ); }
template< > inline Float4 min<Float4>( const Float4 &valueA, const Float4 &valueB )
{ return Float4( min(valueA.xyz, valueB.xyz), min(valueA.w, valueB.w) ); }
template< > inline Float2x2 abs<Float2x2>( const Float2x2 &value )
{ return Float2x2( abs(value.v[0]), abs(value.v[1]) ); }
template< > inline Float2x2 max<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB )
{ return Float2x2( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]) ); }
template< > inline Float2x2 min<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB )
{ return Float2x2( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]) ); }
template< > inline Float3x3 abs<Float3x3>( const Float3x3 &value )
{ return Float3x3( abs(value.v[0]), abs(value.v[1]), abs(value[2]) ); }
template< > inline Float3x3 max<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB )
{ return Float3x3( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]) ); }
template< > inline Float3x3 min<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB )
{ return Float3x3( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]) ); }
template< > inline Float4x4 abs<Float4x4>( const Float4x4 &value )
{ return Float4x4( abs(value.v[0]), abs(value.v[1]), abs(value[2]), abs(value[3]) ); }
template< > inline Float4x4 max<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB )
{ return Float4x4( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]), max(valueA.v[3], valueB.v[3]) ); }
template< > inline Float4x4 min<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB )
{ return Float4x4( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]), min(valueA.v[3], valueB.v[3]) ); }
} }
#endif

183
OysterMath/Quaternion.h Normal file
View File

@ -0,0 +1,183 @@
/////////////////////////////////////////////////////////////////////
// Linear Math Quaternions
// © Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LINEARALGEBRA_QUATERNION_H
#define LINEARALGEBRA_QUATERNION_H
#include "Vector.h"
#include <math.h>
namespace LinearAlgebra
{
template<typename ElementType>
class Quaternion
{
public:
union
{
struct{ Vector3<ElementType> imaginary; ElementType real; };
ElementType element[4];
char byte[sizeof(ElementType[2])];
};
Quaternion( );
Quaternion( const Quaternion &quaternion );
Quaternion( const Vector3<ElementType> &imaginary, const ElementType &real );
~Quaternion( );
operator ElementType* ( );
operator const ElementType* ( ) const;
operator char* ( );
operator const char* ( ) const;
ElementType & operator [] ( int i );
const ElementType & operator [] ( int i ) const;
Quaternion<ElementType> & operator = ( const Quaternion<ElementType> &quaternion );
Quaternion<ElementType> & operator *= ( const ElementType &scalar );
Quaternion<ElementType> & operator /= ( const ElementType &scalar );
Quaternion<ElementType> & operator += ( const Quaternion<ElementType> &quaternion );
Quaternion<ElementType> & operator -= ( const Quaternion<ElementType> &quaternion );
Quaternion<ElementType> operator * ( const Quaternion<ElementType> &quaternion ) const;
Quaternion<ElementType> operator * ( const Vector3<ElementType> &vector ) const;
Quaternion<ElementType> operator * ( const ElementType &scalar ) const;
Quaternion<ElementType> operator / ( const ElementType &scalar ) const;
Quaternion<ElementType> operator + ( const Quaternion<ElementType> &quaternion ) const;
Quaternion<ElementType> operator - ( const Quaternion<ElementType> &quaternion ) const;
Quaternion<ElementType> operator - ( ) const;
Quaternion<ElementType> getConjugate( ) const;
};
///////////////////////////////////////////////////////////////////////////////////
// Body
///////////////////////////////////////////////////////////////////////////////////
template<typename ElementType>
Quaternion<ElementType>::Quaternion( ) : imaginary(0,0,0), real(0) {}
template<typename ElementType>
Quaternion<ElementType>::Quaternion( const Quaternion &quaternion ) : imaginary(quaternion.imaginary), real(quaternion.real) {}
template<typename ElementType>
Quaternion<ElementType>::Quaternion( const Vector3<ElementType> &_imaginary, const ElementType &_real ) : imaginary(_imaginary), real(_real) {}
template<typename ElementType>
Quaternion<ElementType>::~Quaternion( ) { /* Nothing that needs to be done */ }
template<typename ElementType>
inline Quaternion<ElementType>::operator ElementType* ( )
{ return this->element; }
template<typename ElementType>
inline Quaternion<ElementType>::operator const ElementType* ( ) const
{ return this->element; }
template<typename ElementType>
inline Quaternion<ElementType>::operator char* ( )
{ return this->byte; }
template<typename ElementType>
inline Quaternion<ElementType>::operator const char* ( ) const
{ return this->byte; }
template<typename ElementType>
inline ElementType & Quaternion<ElementType>::operator [] ( int i )
{ return this->element[i]; }
template<typename ElementType>
inline const ElementType & Quaternion<ElementType>::operator [] ( int i ) const
{ return this->element[i]; }
template<typename ElementType>
Quaternion<ElementType> & Quaternion<ElementType>::operator = ( const Quaternion<ElementType> &quaternion )
{
this->imaginary = quaternion.imaginary;
this->real = quaternion.real;
return *this;
}
template<typename ElementType>
Quaternion<ElementType> & Quaternion<ElementType>::operator *= ( const ElementType &scalar )
{
this->imaginary *= scalar;
this->real *= scalar;
return *this;
}
template<typename ElementType>
Quaternion<ElementType> & Quaternion<ElementType>::operator /= ( const ElementType &scalar )
{
this->imaginary /= scalar;
this->real /= scalar;
return *this;
}
template<typename ElementType>
Quaternion<ElementType> & Quaternion<ElementType>::operator += ( const Quaternion<ElementType> &quaternion )
{
this->imaginary += quaternion.imaginary;
this->real += quaternion.real;
return *this;
}
template<typename ElementType>
Quaternion<ElementType> & Quaternion<ElementType>::operator -= ( const Quaternion<ElementType> &quaternion )
{
this->imaginary -= quaternion.imaginary;
this->real -= quaternion.real;
return *this;
}
template<typename ElementType>
Quaternion<ElementType> Quaternion<ElementType>::operator * ( const Quaternion<ElementType> &quaternion ) const
{
Vector3<ElementType> im = this->imaginary.cross( quaternion.imaginary );
im += (quaternion.imaginary * this->real);
im += (this->imaginary * quaternion.real);
ElementType re = this->real * quaternion.real;
re -= this->imaginary.dot( quaternion.imaginary );
return Quaternion<ElementType>( im, re );
}
template<typename ElementType>
Quaternion<ElementType> Quaternion<ElementType>::operator * ( const Vector3<ElementType> &vector ) const
{
Vector3<ElementType> im = this->imaginary.cross( vector );
im += (vector * this->real);
ElementType re = this->imaginary.dot( vector ) * -1;
return Quaternion<ElementType>( im, re );
}
template<typename ElementType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator * ( const ElementType &scalar ) const
{ return Quaternion<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator / ( const ElementType &scalar ) const
{ return Quaternion<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator + ( const Quaternion<ElementType> &quaternion ) const
{ return Quaternion<ElementType>(*this) += quaternion; }
template<typename ElementType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator - ( const Quaternion<ElementType> &quaternion ) const
{ return Quaternion<ElementType>(*this) -= quaternion; }
template<typename ElementType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator - ( ) const
{ return Quaternion<ElementType>(-this->imaginary, -this->real); }
template<typename ElementType>
inline Quaternion<ElementType> Quaternion<ElementType>::getConjugate( ) const
{ return Quaternion<ElementType>(this->imaginary * -1, this->real ); }
}
#endif

659
OysterMath/Vector.h Normal file
View File

@ -0,0 +1,659 @@
/////////////////////////////////////////////////////////////////////
// Linear Math Vectors
// © Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LINEARALGEBRA_VECTOR_H
#define LINEARALGEBRA_VECTOR_H
#include <math.h>
namespace LinearAlgebra
{
template<typename ElementType>
class Vector2
{
public:
union
{
struct { ElementType x, y; };
ElementType element[2];
char byte[sizeof(ElementType[2])];
};
static const Vector2<ElementType> null;
static const Vector2<ElementType> standardUnitX;
static const Vector2<ElementType> standardUnitY;
Vector2( );
Vector2( const Vector2<ElementType> &vector );
Vector2( const ElementType &element );
Vector2( const ElementType element[2] );
Vector2( const ElementType &x, const ElementType &y );
~Vector2( );
operator ElementType* ( );
operator const ElementType* ( ) const;
operator char* ( );
operator const char* ( ) const;
ElementType & operator [] ( int i );
const ElementType & operator [] ( int i ) const;
Vector2<ElementType> & operator = ( const Vector2<ElementType> &vector );
Vector2<ElementType> & operator = ( const ElementType element[2] );
Vector2<ElementType> & operator *= ( const ElementType &scalar );
Vector2<ElementType> & operator /= ( const ElementType &scalar );
Vector2<ElementType> & operator += ( const Vector2<ElementType> &vector );
Vector2<ElementType> & operator -= ( const Vector2<ElementType> &vector );
Vector2<ElementType> operator * ( const ElementType &scalar ) const;
Vector2<ElementType> operator / ( const ElementType &scalar ) const;
Vector2<ElementType> operator + ( const Vector2<ElementType> &vector ) const;
Vector2<ElementType> operator - ( const Vector2<ElementType> &vector ) const;
Vector2<ElementType> operator - ( ) const; // unary negation
bool operator == ( const Vector2<ElementType> &vector ) const;
bool operator != ( const Vector2<ElementType> &vector ) const;
ElementType length( ) const;
ElementType dot( const Vector2<ElementType> &vector ) const;
Vector2<ElementType> & normalize( );
Vector2<ElementType> getNormalized( ) const;
};
template<typename ElementType>
class Vector3
{
public:
union
{
struct { ElementType x, y, z; };
struct { Vector2<ElementType> xy; };
ElementType element[3];
char byte[sizeof(ElementType[3])];
};
static const Vector3<ElementType> null;
static const Vector3<ElementType> standardUnitX;
static const Vector3<ElementType> standardUnitY;
static const Vector3<ElementType> standardUnitZ;
Vector3( );
Vector3( const Vector3<ElementType> &vector );
Vector3( const Vector2<ElementType> &vector, const ElementType &z );
Vector3( const ElementType &element );
Vector3( const ElementType element[3] );
Vector3( const ElementType &x, const ElementType &y, const ElementType &z );
~Vector3( );
operator ElementType* ();
operator const ElementType* () const;
operator char* ( );
operator const char* ( ) const;
ElementType & operator [] ( int i );
const ElementType & operator [] ( int i ) const;
Vector3<ElementType> & operator = ( const Vector3<ElementType> &vector );
Vector3<ElementType> & operator = ( const ElementType element[3] );
Vector3<ElementType> & operator *= ( const ElementType &scalar );
Vector3<ElementType> & operator /= ( const ElementType &scalar );
Vector3<ElementType> & operator += ( const Vector3<ElementType> &vector );
Vector3<ElementType> & operator -= ( const Vector3<ElementType> &vector );
Vector3<ElementType> operator * ( const ElementType &scalar ) const;
Vector3<ElementType> operator / ( const ElementType &scalar ) const;
Vector3<ElementType> operator + ( const Vector3<ElementType> &vector ) const;
Vector3<ElementType> operator - ( const Vector3<ElementType> &vector ) const;
Vector3<ElementType> operator - ( ) const; // unary negation
bool operator == ( const Vector3<ElementType> &vector ) const;
bool operator != ( const Vector3<ElementType> &vector ) const;
ElementType length( ) const;
ElementType dot( const Vector3<ElementType> &vector ) const;
Vector3<ElementType> cross( const Vector3<ElementType> &vector ) const;
Vector3<ElementType> & normalize( );
Vector3<ElementType> getNormalized( ) const;
};
template<typename ElementType>
class Vector4
{
public:
union
{
struct { ElementType x, y, z, w; };
struct { Vector2<ElementType> xy; };
struct { Vector3<ElementType> xyz; };
ElementType element[4];
char byte[sizeof(ElementType[4])];
};
static const Vector4<ElementType> null;
static const Vector4<ElementType> standardUnitX;
static const Vector4<ElementType> standardUnitY;
static const Vector4<ElementType> standardUnitZ;
static const Vector4<ElementType> standardUnitW;
Vector4( );
Vector4( const Vector4<ElementType> &vector );
Vector4( const Vector3<ElementType> &vector, const ElementType &w );
Vector4( const Vector2<ElementType> &vector, const ElementType &z, const ElementType &w );
Vector4( const ElementType &element );
Vector4( const ElementType element[4] );
Vector4( const ElementType &x, const ElementType &y, const ElementType &z, const ElementType &w );
~Vector4( );
operator ElementType* ();
operator const ElementType* () const;
operator char* ( );
operator const char* ( ) const;
ElementType & operator [] ( int i );
const ElementType & operator [] ( int i ) const;
Vector4<ElementType> & operator = ( const Vector4<ElementType> &vector );
Vector4<ElementType> & operator = ( const ElementType element[4] );
Vector4<ElementType> & operator *= ( const ElementType &scalar );
Vector4<ElementType> & operator /= ( const ElementType &scalar );
Vector4<ElementType> & operator += ( const Vector4<ElementType> &vector );
Vector4<ElementType> & operator -= ( const Vector4<ElementType> &vector );
Vector4<ElementType> operator * ( const ElementType &scalar ) const;
Vector4<ElementType> operator / ( const ElementType &scalar ) const;
Vector4<ElementType> operator + ( const Vector4<ElementType> &vector ) const;
Vector4<ElementType> operator - ( const Vector4<ElementType> &vector ) const;
Vector4<ElementType> operator - ( ) const; // unary negation
bool operator == ( const Vector4<ElementType> &vector ) const;
bool operator != ( const Vector4<ElementType> &vector ) const;
ElementType length( ) const;
ElementType dot( const Vector4<ElementType> &vector ) const;
Vector4<ElementType> & normalize( );
Vector4<ElementType> getNormalized( ) const;
};
///////////////////////////////////////////////////////////////////////////////////
// Body
///////////////////////////////////////////////////////////////////////////////////
// Vector2<ElementType> ///////////////////////////////////////
template<typename ElementType> const Vector2<ElementType> Vector2<ElementType>::null = Vector2<ElementType>( );
template<typename ElementType> const Vector2<ElementType> Vector2<ElementType>::standardUnitX = Vector2<ElementType>( 1, 0 );
template<typename ElementType> const Vector2<ElementType> Vector2<ElementType>::standardUnitY = Vector2<ElementType>( 0, 1 );
template<typename ElementType>
Vector2<ElementType>::Vector2( ) : x(0), y(0) {}
template<typename ElementType>
Vector2<ElementType>::Vector2( const Vector2<ElementType> &vector ) : x(vector.x), y(vector.y)
{ this->x = vector.x; this->y = vector.y; }
template<typename ElementType>
Vector2<ElementType>::Vector2( const ElementType &_element ) : x(_element), y(_element)
{ this->x = this->y = _element; }
template<typename ElementType>
Vector2<ElementType>::Vector2( const ElementType _element[2] ) : x(_element[0]), y(_element[1]) {}
template<typename ElementType>
Vector2<ElementType>::Vector2( const ElementType &_x, const ElementType &_y ) : x(_x), y(_y) {}
template<typename ElementType>
Vector2<ElementType>::~Vector2( ) { /* Nothing that needs to be done */ }
template<typename ElementType>
inline Vector2<ElementType>::operator ElementType* ()
{ return this->element; }
template<typename ElementType>
inline Vector2<ElementType>::operator const ElementType* () const
{ return this->element; }
template<typename ElementType>
inline Vector2<ElementType>::operator char* ( )
{ return this->byte; }
template<typename ElementType>
inline Vector2<ElementType>::operator const char* ( ) const
{ return this->byte; }
template<typename ElementType>
inline ElementType & Vector2<ElementType>::operator [] ( int i )
{ return this->element[i]; }
template<typename ElementType>
inline const ElementType & Vector2<ElementType>::operator [] ( int i ) const
{ return this->element[i]; }
template<typename ElementType>
Vector2<ElementType> & Vector2<ElementType>::operator = ( const Vector2<ElementType> &vector )
{
this->element[0] = vector.element[0];
this->element[1] = vector.element[1];
return *this;
}
template<typename ElementType>
Vector2<ElementType> & Vector2<ElementType>::operator = ( const ElementType _element[2] )
{
this->element[0] = _element[0];
this->element[1] = _element[1];
return *this;
}
template<typename ElementType>
Vector2<ElementType> & Vector2<ElementType>::operator *= ( const ElementType &scalar )
{
this->element[0] *= scalar;
this->element[1] *= scalar;
return *this;
}
template<typename ElementType>
Vector2<ElementType> & Vector2<ElementType>::operator /= ( const ElementType &scalar )
{
this->element[0] /= scalar;
this->element[1] /= scalar;
return *this;
}
template<typename ElementType>
Vector2<ElementType> & Vector2<ElementType>::operator += ( const Vector2<ElementType> &vector )
{
this->element[0] += vector.element[0];
this->element[1] += vector.element[1];
return *this;
}
template<typename ElementType>
Vector2<ElementType> & Vector2<ElementType>::operator -= ( const Vector2<ElementType> &vector )
{
this->element[0] -= vector.element[0];
this->element[1] -= vector.element[1];
return *this;
}
template<typename ElementType>
inline Vector2<ElementType> Vector2<ElementType>::operator * ( const ElementType &scalar ) const
{ return Vector2<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Vector2<ElementType> Vector2<ElementType>::operator / ( const ElementType &scalar ) const
{ return Vector2<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Vector2<ElementType> Vector2<ElementType>::operator + ( const Vector2<ElementType> &vector ) const
{ return Vector2<ElementType>(*this) += vector; }
template<typename ElementType>
inline Vector2<ElementType> Vector2<ElementType>::operator - ( const Vector2<ElementType> &vector ) const
{ return Vector2<ElementType>(*this) -= vector; }
template<typename ElementType>
inline Vector2<ElementType> Vector2<ElementType>::operator - ( ) const
{ return Vector2<ElementType>(-this->x, -this->y); }
template<typename ElementType>
bool Vector2<ElementType>::operator == ( const Vector2<ElementType> &vector ) const
{
if( this->x != vector.x ) return false;
if( this->y != vector.y ) return false;
return true;
}
template<typename ElementType>
bool Vector2<ElementType>::operator != ( const Vector2<ElementType> &vector ) const
{
if( this->x != vector.x ) return true;
if( this->y != vector.y ) return true;
return false;
}
template<typename ElementType>
inline ElementType Vector2<ElementType>::length( ) const
{ return (ElementType) ::sqrt( this->dot(*this) ); }
template<typename ElementType>
ElementType Vector2<ElementType>::dot( const Vector2<ElementType> &vector ) const
{
ElementType value = 0;
value += this->element[0] * vector.element[0];
value += this->element[1] * vector.element[1];
return value;
}
template<typename ElementType>
inline Vector2<ElementType> & Vector2<ElementType>::normalize( )
{ return (*this) /= this->length(); }
template<typename ElementType>
inline Vector2<ElementType> Vector2<ElementType>::getNormalized( ) const
{ return Vector2<ElementType>(*this).normalize(); }
// Vector3<ElementType> ///////////////////////////////////////
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::null = Vector3<ElementType>( );
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::standardUnitX = Vector3<ElementType>( 1, 0, 0 );
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::standardUnitY = Vector3<ElementType>( 0, 1, 0 );
template<typename ElementType> const Vector3<ElementType> Vector3<ElementType>::standardUnitZ = Vector3<ElementType>( 0, 0, 1 );
template<typename ElementType>
Vector3<ElementType>::Vector3( ) : x(0), y(0), z(0) {}
template<typename ElementType>
Vector3<ElementType>::Vector3( const Vector3<ElementType> &vector ) : x(vector.x), y(vector.y), z(vector.z)
{ this->x = vector.x; this->y = vector.y; this->z = vector.z; }
template<typename ElementType>
Vector3<ElementType>::Vector3( const Vector2<ElementType> &vector, const ElementType &_z ) : x(vector.x), y(vector.y), z(_z)
{ this->x = vector.x; this->y = vector.y; }
template<typename ElementType>
Vector3<ElementType>::Vector3( const ElementType &_element ) : x(_element), y(_element), z(_element)
{ this->x = this->y = this->z = _element; }
template<typename ElementType>
Vector3<ElementType>::Vector3( const ElementType _element[3] ) : x(_element[0]), y(_element[1]), z(_element[2]) {}
template<typename ElementType>
Vector3<ElementType>::Vector3( const ElementType &_x, const ElementType &_y, const ElementType &_z ) : x(_x), y(_y), z(_z)
{ this->x = _x; this->y = _y; this->z = _z; }
template<typename ElementType>
Vector3<ElementType>::~Vector3( ) { /* Nothing that needs to be done */ }
template<typename ElementType>
inline Vector3<ElementType>::operator ElementType* ()
{ return this->element; }
template<typename ElementType>
inline Vector3<ElementType>::operator const ElementType* () const
{ return this->element; }
template<typename ElementType>
inline ElementType & Vector3<ElementType>::operator [] ( int i )
{ return this->element[i]; }
template<typename ElementType>
inline const ElementType & Vector3<ElementType>::operator [] ( int i ) const
{ return this->element[i]; }
template<typename ElementType>
Vector3<ElementType> & Vector3<ElementType>::operator = ( const Vector3<ElementType> &vector )
{
for( int i = 0; i < 3; ++i )
this->element[i] = vector.element[i];
return *this;
}
template<typename ElementType>
Vector3<ElementType> & Vector3<ElementType>::operator = ( const ElementType element[3] )
{
for( int i = 0; i < 3; ++i )
this->element[i] = element[i];
return *this;
}
template<typename ElementType>
Vector3<ElementType> & Vector3<ElementType>::operator *= ( const ElementType &scalar )
{
for( int i = 0; i < 3; ++i )
this->element[i] *= scalar;
return *this;
}
template<typename ElementType>
Vector3<ElementType> & Vector3<ElementType>::operator /= ( const ElementType &scalar )
{
for( int i = 0; i < 3; ++i )
this->element[i] /= scalar;
return *this;
}
template<typename ElementType>
Vector3<ElementType> & Vector3<ElementType>::operator += ( const Vector3<ElementType> &vector )
{
for( int i = 0; i < 3; ++i )
this->element[i] += vector.element[i];
return *this;
}
template<typename ElementType>
Vector3<ElementType> & Vector3<ElementType>::operator -= ( const Vector3<ElementType> &vector )
{
for( int i = 0; i < 3; ++i )
this->element[i] -= vector.element[i];
return *this;
}
template<typename ElementType>
inline Vector3<ElementType> Vector3<ElementType>::operator * ( const ElementType &scalar ) const
{ return Vector3<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Vector3<ElementType> Vector3<ElementType>::operator / ( const ElementType &scalar ) const
{ return Vector3<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Vector3<ElementType> Vector3<ElementType>::operator + ( const Vector3<ElementType> &vector ) const
{ return Vector3<ElementType>(*this) += vector; }
template<typename ElementType>
inline Vector3<ElementType> Vector3<ElementType>::operator - ( const Vector3<ElementType> &vector ) const
{ return Vector3<ElementType>(*this) -= vector; }
template<typename ElementType>
inline Vector3<ElementType> Vector3<ElementType>::operator - ( ) const
{ return Vector3<ElementType>(-this->x, -this->y, -this->z); }
template<typename ElementType>
bool Vector3<ElementType>::operator == ( const Vector3<ElementType> &vector ) const
{
if( this->x != vector.x ) return false;
if( this->y != vector.y ) return false;
if( this->z != vector.z ) return false;
return true;
}
template<typename ElementType>
bool Vector3<ElementType>::operator != ( const Vector3<ElementType> &vector ) const
{
if( this->x != vector.x ) return true;
if( this->y != vector.y ) return true;
if( this->z != vector.z ) return true;
return false;
}
template<typename ElementType>
inline ElementType Vector3<ElementType>::length( ) const
{ return (ElementType) ::sqrt( this->dot(*this) ); }
template<typename ElementType>
ElementType Vector3<ElementType>::dot( const Vector3<ElementType> &vector ) const
{
ElementType value = 0;
for( int i = 0; i < 3; ++i )
value += this->element[i] * vector.element[i];
return value;
}
template<typename ElementType>
Vector3<ElementType> Vector3<ElementType>::cross( const Vector3<ElementType> &vector ) const
{
return Vector3<ElementType>( (this->y*vector.z) - (this->z*vector.y),
(this->z*vector.x) - (this->x*vector.z),
(this->x*vector.y) - (this->y*vector.x) );
}
template<typename ElementType>
inline Vector3<ElementType> & Vector3<ElementType>::normalize( )
{ return (*this) /= this->length(); }
template<typename ElementType>
inline Vector3<ElementType> Vector3<ElementType>::getNormalized( ) const
{ return Vector3<ElementType>(*this).normalize(); }
// Vector4<ElementType> ///////////////////////////////////////
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::null = Vector4<ElementType>( );
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitX = Vector4<ElementType>( 1, 0, 0, 0 );
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitY = Vector4<ElementType>( 0, 1, 0, 0 );
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitZ = Vector4<ElementType>( 0, 0, 1, 0 );
template<typename ElementType> const Vector4<ElementType> Vector4<ElementType>::standardUnitW = Vector4<ElementType>( 0, 0, 0, 1 );
template<typename ElementType>
Vector4<ElementType>::Vector4( ) : x(0), y(0), z(0), w(0) {}
template<typename ElementType>
Vector4<ElementType>::Vector4( const Vector4<ElementType> &vector ) : x(vector.x), y(vector.y), z(vector.z), w(vector.z)
{ this->x = vector.x; this->y = vector.y; this->z = vector.z; this->w = vector.w; }
template<typename ElementType>
Vector4<ElementType>::Vector4( const Vector3<ElementType> &vector, const ElementType &_w ) : x(vector.x), y(vector.y), z(vector.z), w(_w)
{ this->x = vector.x; this->y = vector.y; this->z = vector.z; }
template<typename ElementType>
Vector4<ElementType>::Vector4( const Vector2<ElementType> &vector, const ElementType &_z, const ElementType &_w ) : x(vector.x), y(vector.y), z(_z), w(_w)
{ this->x = vector.x; this->y = vector.y; this->z = _z; this->w = _w; }
template<typename ElementType>
Vector4<ElementType>::Vector4( const ElementType &_element ) : x(_element), y(_element), z(_element), w(_element)
{ this->x = this->y = this->z = this->w = _element; }
template<typename ElementType>
Vector4<ElementType>::Vector4( const ElementType _element[4] ) : x(_element[0]), y(_element[1]), z(_element[2]), w(_element[3]) {}
template<typename ElementType>
Vector4<ElementType>::Vector4( const ElementType &_x, const ElementType &_y, const ElementType &_z, const ElementType &_w ) : x(_x), y(_y), z(_z), w(_w)
{ this->x = _x; this->y = _y; this->z = _z; this->w = _w; }
template<typename ElementType>
Vector4<ElementType>::~Vector4( ) { /* Nothing that needs to be done */ }
template<typename ElementType>
inline Vector4<ElementType>::operator ElementType* ()
{ return this->element; }
template<typename ElementType>
inline Vector4<ElementType>::operator const ElementType* () const
{ return this->element; }
template<typename ElementType>
inline ElementType & Vector4<ElementType>::operator [] ( int i )
{ return this->element[i]; }
template<typename ElementType>
inline const ElementType & Vector4<ElementType>::operator [] ( int i ) const
{ return this->element[i]; }
template<typename ElementType>
Vector4<ElementType> & Vector4<ElementType>::operator = ( const Vector4<ElementType> &vector )
{
for( int i = 0; i < 4; ++i )
this->element[i] = vector.element[i];
return *this;
}
template<typename ElementType>
Vector4<ElementType> & Vector4<ElementType>::operator = ( const ElementType element[4] )
{
for( int i = 0; i < 4; ++i )
this->element[i] = element[i];
return *this;
}
template<typename ElementType>
Vector4<ElementType> & Vector4<ElementType>::operator *= ( const ElementType &scalar )
{
for( int i = 0; i < 4; ++i )
this->element[i] *= scalar;
return *this;
}
template<typename ElementType>
Vector4<ElementType> & Vector4<ElementType>::operator /= ( const ElementType &scalar )
{
for( int i = 0; i < 4; ++i )
this->element[i] /= scalar;
return *this;
}
template<typename ElementType>
Vector4<ElementType> & Vector4<ElementType>::operator += ( const Vector4<ElementType> &vector )
{
for( int i = 0; i < 4; ++i )
this->element[i] += vector.element[i];
return *this;
}
template<typename ElementType>
Vector4<ElementType> & Vector4<ElementType>::operator -= ( const Vector4<ElementType> &vector )
{
for( int i = 0; i < 4; ++i )
this->element[i] -= vector.element[i];
return *this;
}
template<typename ElementType>
inline Vector4<ElementType> Vector4<ElementType>::operator * ( const ElementType &scalar ) const
{ return Vector4<ElementType>(*this) *= scalar; }
template<typename ElementType>
inline Vector4<ElementType> Vector4<ElementType>::operator / ( const ElementType &scalar ) const
{ return Vector4<ElementType>(*this) /= scalar; }
template<typename ElementType>
inline Vector4<ElementType> Vector4<ElementType>::operator + ( const Vector4<ElementType> &vector ) const
{ return Vector4<ElementType>(*this) += vector; }
template<typename ElementType>
inline Vector4<ElementType> Vector4<ElementType>::operator - ( const Vector4<ElementType> &vector ) const
{ return Vector4<ElementType>(*this) -= vector; }
template<typename ElementType>
inline Vector4<ElementType> Vector4<ElementType>::operator - ( ) const
{ return Vector4<ElementType>(-this->x, -this->y, -this->z, -this->w); }
template<typename ElementType>
bool Vector4<ElementType>::operator == ( const Vector4<ElementType> &vector ) const
{
if( this->x != vector.x ) return false;
if( this->y != vector.y ) return false;
if( this->z != vector.z ) return false;
if( this->w != vector.w ) return false;
return true;
}
template<typename ElementType>
bool Vector4<ElementType>::operator != ( const Vector4<ElementType> &vector ) const
{
if( this->x != vector.x ) return true;
if( this->y != vector.y ) return true;
if( this->z != vector.z ) return true;
if( this->w != vector.w ) return true;
return false;
}
template<typename ElementType>
inline ElementType Vector4<ElementType>::length( ) const
{ return (ElementType) ::sqrt( this->dot(*this) ); }
template<typename ElementType>
ElementType Vector4<ElementType>::dot( const Vector4<ElementType> &vector ) const
{
ElementType value = 0;
for( int i = 0; i < 4; ++i )
value += this->element[i] * vector.element[i];
return value;
}
template<typename ElementType>
inline Vector4<ElementType> & Vector4<ElementType>::normalize( )
{ return (*this) /= this->length(); }
template<typename ElementType>
inline Vector4<ElementType> Vector4<ElementType>::getNormalized( ) const
{ return Vector4<ElementType>(*this).normalize(); }
}
#endif

View File

@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////
// Created by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#include "Box.h"
#include "Collision.h"
using namespace ::Oyster::Collision;
using namespace ::Oyster::Math;
Box::Box( ) : ICollideable(ICollideable::Box), orientation(Float4x4::identity), boundingOffset() {}
Box::Box( const Box &box ) : ICollideable(ICollideable::Box), orientation(box.orientation), boundingOffset(box.boundingOffset)
{
this->orientation = box.orientation;
}
Box::Box( const Float4x4 &o, const Float3 &s ) : ICollideable(ICollideable::Box), orientation(o), boundingOffset(s*0.5)
{
this->orientation = o;
}
Box::~Box( ) { /*Nothing needs to be done here*/ }
Box & Box::operator = ( const Box &box )
{
this->orientation = box.orientation;
this->boundingOffset = box.boundingOffset;
return *this;
}
ICollideable* Box::clone( ) const
{ return new Box( *this ); }
bool Box::Intersects( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Ray: return Utility::intersect( *this, *(Collision::Ray*)target, ((Collision::Ray*)target)->collisionDistance );
case ICollideable::Sphere: return Utility::intersect( *this, *(Collision::Sphere*)target );
case ICollideable::Plane: return Utility::intersect( *this, *(Collision::Plane*)target );
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return Utility::intersect( *this, *(Collision::BoxAxisAligned*)target );
case ICollideable::Box: return Utility::intersect( *this, *(Collision::Box*)target );
case ICollideable::Frustrum: return false; // TODO
default: return false;
}
}
bool Box::Contains( const ICollideable *target ) const
{
switch( target->type )
{
case ICollideable::Point: return Utility::intersect( *this, *(Collision::Point*)target );
case ICollideable::Sphere: return false; // TODO
case ICollideable::Triangle: return false; // TODO
case ICollideable::BoxAxisAligned: return false; // TODO
case ICollideable::Box: return false; // TODO
case ICollideable::Frustrum: return false; // TODO
default: return false;
}
}
ICollideable::State Box::Advanced( const ICollideable *target ) const
{ return ICollideable::Missed; } //Not supported returns 0

Some files were not shown because too many files have changed in this diff Show More