├── Engine ├── Resource.h ├── chili.ico ├── tiny_obj_loader.cpp ├── Resource.rc ├── Images │ ├── wall.jpg │ ├── wood.jpg │ ├── ceiling.jpg │ ├── ceiling.png │ ├── floor.jpg │ ├── floor.png │ ├── dice_skin.png │ ├── stonewall.jpg │ ├── stonewall.png │ ├── office_skin.jpg │ ├── office_skin_lores.png │ └── sauron-bhole-100x100.png ├── Triangle.h ├── FrameTimer.h ├── FrameTimer.cpp ├── DefaultGeometryShader.h ├── NatvisFile.natvis ├── Scene.h ├── MouseTracker.h ├── BaseVertexShader.h ├── TestTriangle.h ├── NDCScreenTransformer.h ├── ZBuffer.h ├── GDIPlusManager.h ├── FramebufferPS.hlsl ├── FramebufferVS.hlsl ├── ChiliMath.h ├── GDIPlusManager.cpp ├── ChiliException.h ├── CubeVertexPositionColorScene.h ├── Game.h ├── CubeSkinScene.h ├── BasePhongShader.h ├── CubeSolidGeometryScene.h ├── VertexColorEffect.h ├── CubeSolidScene.h ├── ChiliWin.h ├── CubeVertexColorScene.h ├── TextureEffect.h ├── DoubleCubeScene.h ├── Keyboard.h ├── Sphere.h ├── CubeFlatIndependentScene.h ├── MainWindow.h ├── GouraudScene.h ├── Main.cpp ├── GeometryFlatScene.h ├── DXErr.h ├── VertexWaveScene.h ├── Rect.h ├── SpecularPhongPointEffect.h ├── Vec2.h ├── Keyboard.cpp ├── Plane.h ├── SolidEffect.h ├── Game.cpp ├── Mouse.cpp ├── Mouse.h ├── GouraudPointScene.h ├── PhongPointScene.h ├── VertexPositionColorEffect.h ├── SolidGeometryEffect.h ├── Colors.h ├── PhongPointEffect.h ├── Vec3.h ├── VertexFlatEffect.h ├── RippleVertexSpecularPhongEffect.h ├── GouraudEffect.h ├── VertexLightTexturedEffect.h ├── Surface.h ├── Graphics.h ├── GeometryFlatEffect.h ├── Vec4.h ├── GouraudPointEffect.h ├── Surface.cpp ├── WaveVertexTextureEffect.h ├── MainWindow.cpp └── Cube.h ├── Chili Framework 2016 - 3D.sln ├── .gitattributes └── .gitignore /Engine/Resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Resource.h -------------------------------------------------------------------------------- /Engine/chili.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/chili.ico -------------------------------------------------------------------------------- /Engine/tiny_obj_loader.cpp: -------------------------------------------------------------------------------- 1 | #define TINYOBJLOADER_IMPLEMENTATION 2 | #include "tiny_obj_loader.h" -------------------------------------------------------------------------------- /Engine/Resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Resource.rc -------------------------------------------------------------------------------- /Engine/Images/wall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/wall.jpg -------------------------------------------------------------------------------- /Engine/Images/wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/wood.jpg -------------------------------------------------------------------------------- /Engine/Images/ceiling.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/ceiling.jpg -------------------------------------------------------------------------------- /Engine/Images/ceiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/ceiling.png -------------------------------------------------------------------------------- /Engine/Images/floor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/floor.jpg -------------------------------------------------------------------------------- /Engine/Images/floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/floor.png -------------------------------------------------------------------------------- /Engine/Images/dice_skin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/dice_skin.png -------------------------------------------------------------------------------- /Engine/Images/stonewall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/stonewall.jpg -------------------------------------------------------------------------------- /Engine/Images/stonewall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/stonewall.png -------------------------------------------------------------------------------- /Engine/Images/office_skin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/office_skin.jpg -------------------------------------------------------------------------------- /Engine/Images/office_skin_lores.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/office_skin_lores.png -------------------------------------------------------------------------------- /Engine/Images/sauron-bhole-100x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/planetchili/3D_Fundamentals/HEAD/Engine/Images/sauron-bhole-100x100.png -------------------------------------------------------------------------------- /Engine/Triangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class Triangle 5 | { 6 | public: 7 | V v0; 8 | V v1; 9 | V v2; 10 | }; -------------------------------------------------------------------------------- /Engine/FrameTimer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class FrameTimer 5 | { 6 | public: 7 | FrameTimer(); 8 | float Mark(); 9 | private: 10 | std::chrono::steady_clock::time_point last; 11 | }; -------------------------------------------------------------------------------- /Engine/FrameTimer.cpp: -------------------------------------------------------------------------------- 1 | #include "FrameTimer.h" 2 | 3 | using namespace std::chrono; 4 | 5 | FrameTimer::FrameTimer() 6 | { 7 | last = steady_clock::now(); 8 | } 9 | 10 | float FrameTimer::Mark() 11 | { 12 | const auto old = last; 13 | last = steady_clock::now(); 14 | const duration frameTime = last - old; 15 | return frameTime.count(); 16 | } 17 | -------------------------------------------------------------------------------- /Engine/DefaultGeometryShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Triangle.h" 4 | 5 | template 6 | class DefaultGeometryShader 7 | { 8 | public: 9 | typedef Vertex Output; 10 | public: 11 | Triangle operator()( const Vertex& in0,const Vertex& in1,const Vertex& in2,size_t triangle_index ) const 12 | { 13 | return{ in0,in1,in2 }; 14 | } 15 | }; -------------------------------------------------------------------------------- /Engine/NatvisFile.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ {x} , {y} , {z} }} 5 | 6 | 7 | {{ {x} , {y} , {z} , {w} }} 8 | 9 | -------------------------------------------------------------------------------- /Engine/Scene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Keyboard.h" 3 | #include "Mouse.h" 4 | #include "Graphics.h" 5 | #include 6 | 7 | class Scene 8 | { 9 | public: 10 | Scene( const std::string& name ) 11 | : 12 | name( name ) 13 | {} 14 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) = 0; 15 | virtual void Draw() = 0; 16 | virtual ~Scene() = default; 17 | const std::string& GetName() const 18 | { 19 | return name; 20 | } 21 | private: 22 | std::string name; 23 | }; -------------------------------------------------------------------------------- /Engine/MouseTracker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Vec2.h" 3 | 4 | class MouseTracker 5 | { 6 | public: 7 | void Engage( const Vei2& pos ) 8 | { 9 | base = pos; 10 | engaged = true; 11 | } 12 | void Release() 13 | { 14 | engaged = false; 15 | } 16 | Vei2 Move( const Vei2& pos ) 17 | { 18 | const auto delta = pos - base; 19 | base = pos; 20 | return delta; 21 | } 22 | bool Engaged() const 23 | { 24 | return engaged; 25 | } 26 | private: 27 | bool engaged = false; 28 | Vei2 base; 29 | }; -------------------------------------------------------------------------------- /Engine/BaseVertexShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class BaseVertexShader 5 | { 6 | public: 7 | typedef Vertex Output; 8 | public: 9 | void BindWorldView( const Mat4& transformation_in ) 10 | { 11 | worldView = transformation_in; 12 | worldViewProj = worldView * proj; 13 | } 14 | void BindProjection( const Mat4& transformation_in ) 15 | { 16 | proj = transformation_in; 17 | worldViewProj = worldView * proj; 18 | } 19 | const Mat4& GetProj() const 20 | { 21 | return proj; 22 | } 23 | protected: 24 | Mat4 proj = Mat4::Identity(); 25 | Mat4 worldView = Mat4::Identity(); 26 | Mat4 worldViewProj = Mat4::Identity(); 27 | }; -------------------------------------------------------------------------------- /Engine/TestTriangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "Vec2.h" 6 | #include "Vec3.h" 7 | #include "IndexedTriangleList.h" 8 | 9 | class TestTriangle 10 | { 11 | public: 12 | template 13 | static IndexedTriangleList GetPlain() 14 | { 15 | std::vector vertices( 3 ); 16 | vertices[0].pos = { 0.0f,0.8f,0.0f }; 17 | vertices[1].pos = { 0.8f,-0.8f,0.0f }; 18 | vertices[2].pos = { -0.8f,-0.8f,0.0f }; 19 | 20 | std::vector indices; 21 | indices.reserve( 3 ); 22 | indices.push_back( 0 ); 23 | indices.push_back( 1 ); 24 | indices.push_back( 2 ); 25 | 26 | return{ std::move( vertices ),std::move( indices ) }; 27 | } 28 | template 29 | static IndexedTriangleList GetNormals() 30 | { 31 | auto itlist = GetPlain(); 32 | for( auto& v : itlist.vertices ) 33 | { 34 | v.n = { 0.0f,0.0f,-1.0f }; 35 | } 36 | 37 | return itlist; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /Engine/NDCScreenTransformer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Vec3.h" 3 | #include "Graphics.h" 4 | 5 | class NDCScreenTransformer 6 | { 7 | public: 8 | NDCScreenTransformer() 9 | : 10 | xFactor( float( Graphics::ScreenWidth ) / 2.0f ), 11 | yFactor( float( Graphics::ScreenHeight ) / 2.0f ) 12 | {} 13 | template 14 | Vertex& Transform( Vertex& v ) const 15 | { 16 | // perform homo -> ndc on xyz / perspective-correct interpolative divide on all other attributes 17 | const float wInv = 1.0f / v.pos.w; 18 | v *= wInv; 19 | // additional divide for mapped z because it must be interpolated 20 | // adjust position x,y from perspective normalized space 21 | // to screen dimension space after perspective divide 22 | v.pos.x = (v.pos.x + 1.0f) * xFactor; 23 | v.pos.y = (-v.pos.y + 1.0f) * yFactor; 24 | // store 1/w in w (we will need the interpolated 1/w 25 | // so that we can recover the attributes after interp.) 26 | v.pos.w = wInv; 27 | 28 | return v; 29 | } 30 | template 31 | Vertex GetTransformed( const Vertex& v ) const 32 | { 33 | return Transform( Vertex( v ) ); 34 | } 35 | private: 36 | float xFactor; 37 | float yFactor; 38 | }; -------------------------------------------------------------------------------- /Chili Framework 2016 - 3D.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Engine", "Engine\Engine.vcxproj", "{FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Debug|x64.ActiveCfg = Debug|x64 17 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Debug|x64.Build.0 = Debug|x64 18 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Debug|x86.ActiveCfg = Debug|Win32 19 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Debug|x86.Build.0 = Debug|Win32 20 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Release|x64.ActiveCfg = Release|x64 21 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Release|x64.Build.0 = Release|x64 22 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Release|x86.ActiveCfg = Release|Win32 23 | {FFCA512B-49FC-4FC8-8A73-C4F87D322FF2}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /Engine/ZBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class ZBuffer 8 | { 9 | public: 10 | ZBuffer( int width,int height ) 11 | : 12 | width( width ), 13 | height( height ), 14 | pBuffer( new float[width*height] ) 15 | {} 16 | ~ZBuffer() 17 | { 18 | delete[] pBuffer; 19 | pBuffer = nullptr; 20 | } 21 | ZBuffer( const ZBuffer& ) = delete; 22 | ZBuffer& operator=( const ZBuffer& ) = delete; 23 | void Clear() 24 | { 25 | const int nDepths = width * height; 26 | for( int i = 0; i < nDepths; i++ ) 27 | { 28 | pBuffer[i] = std::numeric_limits::infinity(); 29 | } 30 | } 31 | float& At( int x,int y ) 32 | { 33 | assert( x >= 0 ); 34 | assert( x < width ); 35 | assert( y >= 0 ); 36 | assert( y < height ); 37 | return pBuffer[y * width + x]; 38 | } 39 | const float& At( int x,int y ) const 40 | { 41 | return const_cast(this)->At( x,y ); 42 | } 43 | bool TestAndSet( int x,int y,float depth ) 44 | { 45 | float& depthInBuffer = At( x,y ); 46 | if( depth < depthInBuffer ) 47 | { 48 | depthInBuffer = depth; 49 | return true; 50 | } 51 | return false; 52 | } 53 | int GetWidth() const 54 | { 55 | return width; 56 | } 57 | int GetHeight() const 58 | { 59 | return height; 60 | } 61 | auto GetMinMax() const 62 | { 63 | return std::minmax_element( pBuffer,pBuffer + width * height ); 64 | } 65 | private: 66 | int width; 67 | int height; 68 | float* pBuffer = nullptr; 69 | }; -------------------------------------------------------------------------------- /Engine/GDIPlusManager.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * GDIPlusManager.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include "ChiliWin.h" 23 | 24 | class GDIPlusManager 25 | { 26 | public: 27 | GDIPlusManager(); 28 | ~GDIPlusManager(); 29 | private: 30 | static ULONG_PTR token; 31 | static int refCount; 32 | }; -------------------------------------------------------------------------------- /Engine/FramebufferPS.hlsl: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * FramebufferPS.hlsl * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | Texture2D tex : register( t0 ); 22 | SamplerState sam : register( s0 ); 23 | 24 | float4 FramebufferPS( float4 position : SV_POSITION,float2 texCoord : TEXCOORD0 ) : SV_TARGET 25 | { 26 | return tex.Sample( sam,texCoord ); 27 | } -------------------------------------------------------------------------------- /Engine/FramebufferVS.hlsl: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * FramebufferVS.hlsl * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | struct VOut 22 | { 23 | float4 position : SV_POSITION; 24 | float2 texCoord : TEXCOORD0; 25 | }; 26 | 27 | VOut FramebufferVS( float4 position : POSITION,float2 texCoord : TEXCOORD0 ) 28 | { 29 | VOut output; 30 | 31 | output.position = position; 32 | output.texCoord = texCoord; 33 | 34 | return output; 35 | } -------------------------------------------------------------------------------- /Engine/ChiliMath.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * ChiliMath.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include 24 | 25 | constexpr float PI = 3.14159265f; 26 | constexpr double PI_D = 3.1415926535897932; 27 | 28 | template 29 | constexpr auto sq( const T& x ) 30 | { 31 | return x * x; 32 | } 33 | 34 | template 35 | T wrap_angle( T theta ) 36 | { 37 | const T modded = static_cast(fmod( theta,(T)2.0 * (T)PI_D )); 38 | return (modded > (T)PI_D) ? 39 | (modded - (T)2.0 * (T)PI_D) : 40 | modded; 41 | } 42 | 43 | template 44 | constexpr T interpolate( const T& src,const T& dst,float alpha ) 45 | { 46 | return src + (dst - src) * alpha; 47 | } 48 | 49 | template 50 | constexpr T to_rad( T deg ) 51 | { 52 | return deg * PI / (T)180.0; 53 | } -------------------------------------------------------------------------------- /Engine/GDIPlusManager.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * GDIPlusManager.cpp * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #define FULL_WINTARD 22 | #include "ChiliWin.h" 23 | #include "GDIPlusManager.h" 24 | #include 25 | namespace Gdiplus 26 | { 27 | using std::min; 28 | using std::max; 29 | } 30 | #include 31 | 32 | ULONG_PTR GDIPlusManager::token = 0; 33 | int GDIPlusManager::refCount = 0; 34 | 35 | GDIPlusManager::GDIPlusManager() 36 | { 37 | if( refCount++ == 0 ) 38 | { 39 | Gdiplus::GdiplusStartupInput input; 40 | input.GdiplusVersion = 1; 41 | input.DebugEventCallback = nullptr; 42 | input.SuppressBackgroundThread = false; 43 | Gdiplus::GdiplusStartup( &token,&input,nullptr ); 44 | } 45 | } 46 | 47 | GDIPlusManager::~GDIPlusManager() 48 | { 49 | if( --refCount == 0 ) 50 | { 51 | Gdiplus::GdiplusShutdown( token ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Engine/ChiliException.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * ChiliException.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include 23 | 24 | class ChiliException 25 | { 26 | public: 27 | ChiliException( const wchar_t* file,unsigned int line,const std::wstring& note = L"" ) 28 | : 29 | note( note ), 30 | file( file ), 31 | line( line ) 32 | {} 33 | const std::wstring& GetNote() const 34 | { 35 | return note; 36 | } 37 | const std::wstring& GetFile() const 38 | { 39 | return file; 40 | } 41 | unsigned int GetLine() const 42 | { 43 | return line; 44 | } 45 | std::wstring GetLocation() const 46 | { 47 | return std::wstring( L"Line [" ) + std::to_wstring( line ) + L"] in " + file; 48 | } 49 | virtual std::wstring GetFullMessage() const = 0; 50 | virtual std::wstring GetExceptionType() const = 0; 51 | private: 52 | std::wstring note; 53 | std::wstring file; 54 | unsigned int line; 55 | }; -------------------------------------------------------------------------------- /Engine/CubeVertexPositionColorScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "VertexPositionColorEffect.h" 8 | 9 | class CubeVertexPositionColorScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | CubeVertexPositionColorScene( Graphics& gfx ) 16 | : 17 | itlist( Cube::GetPlain() ), 18 | pipeline( gfx ), 19 | Scene( "Cube vertex position color scene" ) 20 | {} 21 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 22 | { 23 | if( kbd.KeyIsPressed( 'Q' ) ) 24 | { 25 | theta_x = wrap_angle( theta_x + dTheta * dt ); 26 | } 27 | if( kbd.KeyIsPressed( 'W' ) ) 28 | { 29 | theta_y = wrap_angle( theta_y + dTheta * dt ); 30 | } 31 | if( kbd.KeyIsPressed( 'E' ) ) 32 | { 33 | theta_z = wrap_angle( theta_z + dTheta * dt ); 34 | } 35 | if( kbd.KeyIsPressed( 'A' ) ) 36 | { 37 | theta_x = wrap_angle( theta_x - dTheta * dt ); 38 | } 39 | if( kbd.KeyIsPressed( 'S' ) ) 40 | { 41 | theta_y = wrap_angle( theta_y - dTheta * dt ); 42 | } 43 | if( kbd.KeyIsPressed( 'D' ) ) 44 | { 45 | theta_z = wrap_angle( theta_z - dTheta * dt ); 46 | } 47 | if( kbd.KeyIsPressed( 'R' ) ) 48 | { 49 | offset_z += 2.0f * dt; 50 | } 51 | if( kbd.KeyIsPressed( 'F' ) ) 52 | { 53 | offset_z -= 2.0f * dt; 54 | } 55 | } 56 | virtual void Draw() override 57 | { 58 | pipeline.BeginFrame(); 59 | // generate rotation matrix from euler angles 60 | // translation from offset 61 | const Mat3 rot = 62 | Mat3::RotationX( theta_x ) * 63 | Mat3::RotationY( theta_y ) * 64 | Mat3::RotationZ( theta_z ); 65 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 66 | // set pipeline transform 67 | pipeline.effect.vs.BindRotation( rot ); 68 | pipeline.effect.vs.BindTranslation( trans ); 69 | // render triangles 70 | pipeline.Draw( itlist ); 71 | } 72 | private: 73 | IndexedTriangleList itlist; 74 | Pipeline pipeline; 75 | static constexpr float dTheta = PI; 76 | float offset_z = 2.0f; 77 | float theta_x = 0.0f; 78 | float theta_y = 0.0f; 79 | float theta_z = 0.0f; 80 | }; -------------------------------------------------------------------------------- /Engine/Game.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Game.h * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include "Graphics.h" 24 | #include 25 | #include 26 | #include "Scene.h" 27 | #include "FrameTimer.h" 28 | 29 | class Game 30 | { 31 | public: 32 | Game( class MainWindow& wnd ); 33 | Game( const Game& ) = delete; 34 | Game& operator=( const Game& ) = delete; 35 | void Go(); 36 | private: 37 | void ComposeFrame(); 38 | void UpdateModel(); 39 | /********************************/ 40 | /* User Functions */ 41 | void CycleScenes(); 42 | void ReverseCycleScenes(); 43 | void OutputSceneName() const; 44 | /********************************/ 45 | private: 46 | MainWindow& wnd; 47 | Graphics gfx; 48 | /********************************/ 49 | /* User Variables */ 50 | FrameTimer ft; 51 | std::vector> scenes; 52 | std::vector>::iterator curScene; 53 | /********************************/ 54 | }; -------------------------------------------------------------------------------- /Engine/CubeSkinScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "TextureEffect.h" 8 | 9 | // scene demonstrating skinned cube 10 | class CubeSkinScene : public Scene 11 | { 12 | public: 13 | typedef Pipeline Pipeline; 14 | typedef Pipeline::Vertex Vertex; 15 | public: 16 | CubeSkinScene( Graphics& gfx,const std::wstring& filename ) 17 | : 18 | itlist( Cube::GetSkinned() ), 19 | pipeline( gfx ), 20 | Scene( "Textured Cube skinned using texture: " + std::string( filename.begin(),filename.end() ) ) 21 | { 22 | pipeline.effect.ps.BindTexture( filename ); 23 | } 24 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 25 | { 26 | if( kbd.KeyIsPressed( 'Q' ) ) 27 | { 28 | theta_x = wrap_angle( theta_x + dTheta * dt ); 29 | } 30 | if( kbd.KeyIsPressed( 'W' ) ) 31 | { 32 | theta_y = wrap_angle( theta_y + dTheta * dt ); 33 | } 34 | if( kbd.KeyIsPressed( 'E' ) ) 35 | { 36 | theta_z = wrap_angle( theta_z + dTheta * dt ); 37 | } 38 | if( kbd.KeyIsPressed( 'A' ) ) 39 | { 40 | theta_x = wrap_angle( theta_x - dTheta * dt ); 41 | } 42 | if( kbd.KeyIsPressed( 'S' ) ) 43 | { 44 | theta_y = wrap_angle( theta_y - dTheta * dt ); 45 | } 46 | if( kbd.KeyIsPressed( 'D' ) ) 47 | { 48 | theta_z = wrap_angle( theta_z - dTheta * dt ); 49 | } 50 | if( kbd.KeyIsPressed( 'R' ) ) 51 | { 52 | offset_z += 2.0f * dt; 53 | } 54 | if( kbd.KeyIsPressed( 'F' ) ) 55 | { 56 | offset_z -= 2.0f * dt; 57 | } 58 | } 59 | virtual void Draw() override 60 | { 61 | pipeline.BeginFrame(); 62 | // generate rotation matrix from euler angles 63 | // translation from offset 64 | const Mat3 rot = 65 | Mat3::RotationX( theta_x ) * 66 | Mat3::RotationY( theta_y ) * 67 | Mat3::RotationZ( theta_z ); 68 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 69 | // set pipeline transform 70 | pipeline.effect.vs.BindRotation( rot ); 71 | pipeline.effect.vs.BindTranslation( trans ); 72 | // render triangles 73 | pipeline.Draw( itlist ); 74 | } 75 | private: 76 | IndexedTriangleList itlist; 77 | Pipeline pipeline; 78 | static constexpr float dTheta = PI; 79 | float offset_z = 2.0f; 80 | float theta_x = 0.0f; 81 | float theta_y = 0.0f; 82 | float theta_z = 0.0f; 83 | }; -------------------------------------------------------------------------------- /Engine/BasePhongShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Colors.h" 3 | #include "Vec3.h" 4 | 5 | struct DefaultPointDiffuseParams 6 | { 7 | static constexpr float linear_attenuation = 1.0f; 8 | static constexpr float quadradic_attenuation = 2.619f; 9 | static constexpr float constant_attenuation = 0.382f; 10 | }; 11 | 12 | struct DefaultSpecularParams 13 | { 14 | static constexpr float specular_power = 30.0f; 15 | static constexpr float specular_intensity = 0.6f; 16 | }; 17 | 18 | template 19 | class BasePhongShader 20 | { 21 | public: 22 | template 23 | Color Shade( const Input& in,const Vec3& material_color ) const 24 | { 25 | // re-normalize interpolated surface normal 26 | const auto surf_norm = in.n.GetNormalized(); 27 | // vertex to light data 28 | const auto v_to_l = light_pos - in.worldPos; 29 | const auto dist = v_to_l.Len(); 30 | const auto dir = v_to_l / dist; 31 | // calculate attenuation 32 | const auto attenuation = 1.0f / 33 | (PointDiffuse::constant_attenuation + PointDiffuse::linear_attenuation * dist + PointDiffuse::quadradic_attenuation * sq( dist )); 34 | // calculate intensity based on angle of incidence and attenuation 35 | const auto d = light_diffuse * attenuation * std::max( 0.0f,surf_norm * dir ); 36 | // reflected light vector 37 | const auto w = surf_norm * (v_to_l * surf_norm); 38 | const auto r = w * 2.0f - v_to_l; 39 | // calculate specular intensity based on angle between viewing vector and reflection vector, narrow with power function 40 | const auto s = light_diffuse * Specular::specular_intensity * std::pow( std::max( 0.0f,-r.GetNormalized() * in.worldPos.GetNormalized() ),Specular::specular_power ); 41 | // add diffuse+ambient, filter by material color, saturate and scale 42 | return Color( material_color.GetHadamard( d + light_ambient + s ).Saturate() * 255.0f ); 43 | } 44 | void SetDiffuseLight( const Vec3& c ) 45 | { 46 | light_diffuse = c; 47 | } 48 | void SetAmbientLight( const Vec3& c ) 49 | { 50 | light_ambient = c; 51 | } 52 | void SetLightPosition( const Vec3& pos_in ) 53 | { 54 | light_pos = pos_in; 55 | } 56 | private: 57 | Vec3 light_pos = { 0.0f,0.0f,0.5f }; 58 | Vec3 light_diffuse = { 1.0f,1.0f,1.0f }; 59 | Vec3 light_ambient = { 0.1f,0.1f,0.1f }; 60 | }; -------------------------------------------------------------------------------- /Engine/CubeSolidGeometryScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "SolidGeometryEffect.h" 8 | 9 | class CubeSolidGeometryScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | CubeSolidGeometryScene( Graphics& gfx ) 16 | : 17 | itlist( Cube::GetPlain() ), 18 | pipeline( gfx ), 19 | Scene( "Colored cube geometry solid face scene" ) 20 | { 21 | pipeline.effect.gs.BindColors( 22 | { Colors::Red,Colors::Green,Colors::Blue,Colors::Magenta,Colors::Yellow,Colors::Cyan } 23 | ); 24 | } 25 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 26 | { 27 | if( kbd.KeyIsPressed( 'Q' ) ) 28 | { 29 | theta_x = wrap_angle( theta_x + dTheta * dt ); 30 | } 31 | if( kbd.KeyIsPressed( 'W' ) ) 32 | { 33 | theta_y = wrap_angle( theta_y + dTheta * dt ); 34 | } 35 | if( kbd.KeyIsPressed( 'E' ) ) 36 | { 37 | theta_z = wrap_angle( theta_z + dTheta * dt ); 38 | } 39 | if( kbd.KeyIsPressed( 'A' ) ) 40 | { 41 | theta_x = wrap_angle( theta_x - dTheta * dt ); 42 | } 43 | if( kbd.KeyIsPressed( 'S' ) ) 44 | { 45 | theta_y = wrap_angle( theta_y - dTheta * dt ); 46 | } 47 | if( kbd.KeyIsPressed( 'D' ) ) 48 | { 49 | theta_z = wrap_angle( theta_z - dTheta * dt ); 50 | } 51 | if( kbd.KeyIsPressed( 'R' ) ) 52 | { 53 | offset_z += 2.0f * dt; 54 | } 55 | if( kbd.KeyIsPressed( 'F' ) ) 56 | { 57 | offset_z -= 2.0f * dt; 58 | } 59 | } 60 | virtual void Draw() override 61 | { 62 | pipeline.BeginFrame(); 63 | // generate rotation matrix from euler angles 64 | // translation from offset 65 | const Mat3 rot = 66 | Mat3::RotationX( theta_x ) * 67 | Mat3::RotationY( theta_y ) * 68 | Mat3::RotationZ( theta_z ); 69 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 70 | // set pipeline transform 71 | pipeline.effect.vs.BindRotation( rot ); 72 | pipeline.effect.vs.BindTranslation( trans ); 73 | // render triangles 74 | pipeline.Draw( itlist ); 75 | } 76 | private: 77 | IndexedTriangleList itlist; 78 | Pipeline pipeline; 79 | static constexpr float dTheta = PI; 80 | float offset_z = 2.0f; 81 | float theta_x = 0.0f; 82 | float theta_y = 0.0f; 83 | float theta_z = 0.0f; 84 | }; -------------------------------------------------------------------------------- /Engine/VertexColorEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | 7 | // color gradient effect between vertices 8 | class VertexColorEffect 9 | { 10 | public: 11 | // the vertex type that will be input into the pipeline 12 | class Vertex 13 | { 14 | public: 15 | Vertex() = default; 16 | Vertex( const Vec3& pos ) 17 | : 18 | pos( pos ) 19 | {} 20 | Vertex( const Vec3& pos,const Vertex& src ) 21 | : 22 | color( src.color ), 23 | pos( pos ) 24 | {} 25 | Vertex( const Vec3& pos,const Vec3& color ) 26 | : 27 | color( color ), 28 | pos( pos ) 29 | {} 30 | Vertex& operator+=( const Vertex& rhs ) 31 | { 32 | pos += rhs.pos; 33 | color += rhs.color; 34 | return *this; 35 | } 36 | Vertex operator+( const Vertex& rhs ) const 37 | { 38 | return Vertex( *this ) += rhs; 39 | } 40 | Vertex& operator-=( const Vertex& rhs ) 41 | { 42 | pos -= rhs.pos; 43 | color -= rhs.color; 44 | return *this; 45 | } 46 | Vertex operator-( const Vertex& rhs ) const 47 | { 48 | return Vertex( *this ) -= rhs; 49 | } 50 | Vertex& operator*=( float rhs ) 51 | { 52 | pos *= rhs; 53 | color *= rhs; 54 | return *this; 55 | } 56 | Vertex operator*( float rhs ) const 57 | { 58 | return Vertex( *this ) *= rhs; 59 | } 60 | Vertex& operator/=( float rhs ) 61 | { 62 | pos /= rhs; 63 | color /= rhs; 64 | return *this; 65 | } 66 | Vertex operator/( float rhs ) const 67 | { 68 | return Vertex( *this ) /= rhs; 69 | } 70 | public: 71 | Vec3 pos; 72 | Vec3 color; 73 | }; 74 | // default vs rotates and translates vertices 75 | // does not touch attributes 76 | typedef DefaultVertexShader VertexShader; 77 | // default gs passes vertices through and outputs triangle 78 | typedef DefaultGeometryShader GeometryShader; 79 | // invoked for each pixel of a triangle 80 | // takes an input of attributes that are the 81 | // result of interpolating vertex attributes 82 | // and outputs a color 83 | class PixelShader 84 | { 85 | public: 86 | template 87 | Color operator()( const Input& in ) const 88 | { 89 | return Color( in.color ); 90 | } 91 | }; 92 | public: 93 | VertexShader vs; 94 | GeometryShader gs; 95 | PixelShader ps; 96 | }; -------------------------------------------------------------------------------- /Engine/CubeSolidScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "SolidEffect.h" 8 | 9 | class CubeSolidScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | CubeSolidScene( Graphics& gfx ) 16 | : 17 | itlist( Cube::GetPlainIndependentFaces() ), 18 | pipeline( gfx ), 19 | Scene( "Colored cube solid independent faces scene" ) 20 | { 21 | const Color colors[] = { 22 | Colors::Red,Colors::Green,Colors::Blue,Colors::Magenta,Colors::Yellow,Colors::Cyan 23 | }; 24 | 25 | for( int i = 0; i < itlist.vertices.size(); i++ ) 26 | { 27 | itlist.vertices[i].color = colors[i / 4]; 28 | } 29 | } 30 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 31 | { 32 | if( kbd.KeyIsPressed( 'Q' ) ) 33 | { 34 | theta_x = wrap_angle( theta_x + dTheta * dt ); 35 | } 36 | if( kbd.KeyIsPressed( 'W' ) ) 37 | { 38 | theta_y = wrap_angle( theta_y + dTheta * dt ); 39 | } 40 | if( kbd.KeyIsPressed( 'E' ) ) 41 | { 42 | theta_z = wrap_angle( theta_z + dTheta * dt ); 43 | } 44 | if( kbd.KeyIsPressed( 'A' ) ) 45 | { 46 | theta_x = wrap_angle( theta_x - dTheta * dt ); 47 | } 48 | if( kbd.KeyIsPressed( 'S' ) ) 49 | { 50 | theta_y = wrap_angle( theta_y - dTheta * dt ); 51 | } 52 | if( kbd.KeyIsPressed( 'D' ) ) 53 | { 54 | theta_z = wrap_angle( theta_z - dTheta * dt ); 55 | } 56 | if( kbd.KeyIsPressed( 'R' ) ) 57 | { 58 | offset_z += 2.0f * dt; 59 | } 60 | if( kbd.KeyIsPressed( 'F' ) ) 61 | { 62 | offset_z -= 2.0f * dt; 63 | } 64 | } 65 | virtual void Draw() override 66 | { 67 | pipeline.BeginFrame(); 68 | // generate rotation matrix from euler angles 69 | // translation from offset 70 | const Mat3 rot = 71 | Mat3::RotationX( theta_x ) * 72 | Mat3::RotationY( theta_y ) * 73 | Mat3::RotationZ( theta_z ); 74 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 75 | // set pipeline transform 76 | pipeline.effect.vs.BindRotation( rot ); 77 | pipeline.effect.vs.BindTranslation( trans ); 78 | // render triangles 79 | pipeline.Draw( itlist ); 80 | } 81 | private: 82 | IndexedTriangleList itlist; 83 | Pipeline pipeline; 84 | static constexpr float dTheta = PI; 85 | float offset_z = 2.0f; 86 | float theta_x = 0.0f; 87 | float theta_y = 0.0f; 88 | float theta_z = 0.0f; 89 | }; -------------------------------------------------------------------------------- /Engine/ChiliWin.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * ChiliWin.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | // target Windows 7 or later 24 | #define _WIN32_WINNT 0x0601 25 | #include 26 | // The following #defines disable a bunch of unused windows stuff. If you 27 | // get weird errors when trying to do some windows stuff, try removing some 28 | // (or all) of these defines (it will increase build time though). 29 | #ifndef FULL_WINTARD 30 | #define WIN32_LEAN_AND_MEAN 31 | #define NOGDICAPMASKS 32 | #define NOSYSMETRICS 33 | #define NOMENUS 34 | #define NOICONS 35 | #define NOSYSCOMMANDS 36 | #define NORASTEROPS 37 | #define OEMRESOURCE 38 | #define NOATOM 39 | #define NOCLIPBOARD 40 | #define NOCOLOR 41 | #define NOCTLMGR 42 | #define NODRAWTEXT 43 | #define NOKERNEL 44 | #define NONLS 45 | #define NOMEMMGR 46 | #define NOMETAFILE 47 | #define NOMINMAX 48 | #define NOOPENFILE 49 | #define NOSCROLL 50 | #define NOSERVICE 51 | #define NOSOUND 52 | #define NOTEXTMETRIC 53 | #define NOWH 54 | #define NOCOMM 55 | #define NOKANJI 56 | #define NOHELP 57 | #define NOPROFILER 58 | #define NODEFERWINDOWPOS 59 | #define NOMCX 60 | #define NORPC 61 | #define NOPROXYSTUB 62 | #define NOIMAGE 63 | #define NOTAPE 64 | #endif 65 | 66 | #define NOMINMAX 67 | 68 | #define STRICT 69 | 70 | #include -------------------------------------------------------------------------------- /Engine/CubeVertexColorScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "VertexColorEffect.h" 8 | 9 | class CubeVertexColorScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | CubeVertexColorScene( Graphics& gfx ) 16 | : 17 | itlist( Cube::GetPlain() ), 18 | pipeline( gfx ), 19 | Scene( "Colored cube vertex gradient scene" ) 20 | { 21 | itlist.vertices[0].color = Vec3( Colors::Red ); 22 | itlist.vertices[1].color = Vec3( Colors::Green ); 23 | itlist.vertices[2].color = Vec3( Colors::Blue ); 24 | itlist.vertices[3].color = Vec3( Colors::Yellow ); 25 | itlist.vertices[4].color = Vec3( Colors::Cyan ); 26 | itlist.vertices[5].color = Vec3( Colors::Magenta ); 27 | itlist.vertices[6].color = Vec3( Colors::White ); 28 | itlist.vertices[7].color = Vec3( Colors::Black ); 29 | } 30 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 31 | { 32 | if( kbd.KeyIsPressed( 'Q' ) ) 33 | { 34 | theta_x = wrap_angle( theta_x + dTheta * dt ); 35 | } 36 | if( kbd.KeyIsPressed( 'W' ) ) 37 | { 38 | theta_y = wrap_angle( theta_y + dTheta * dt ); 39 | } 40 | if( kbd.KeyIsPressed( 'E' ) ) 41 | { 42 | theta_z = wrap_angle( theta_z + dTheta * dt ); 43 | } 44 | if( kbd.KeyIsPressed( 'A' ) ) 45 | { 46 | theta_x = wrap_angle( theta_x - dTheta * dt ); 47 | } 48 | if( kbd.KeyIsPressed( 'S' ) ) 49 | { 50 | theta_y = wrap_angle( theta_y - dTheta * dt ); 51 | } 52 | if( kbd.KeyIsPressed( 'D' ) ) 53 | { 54 | theta_z = wrap_angle( theta_z - dTheta * dt ); 55 | } 56 | if( kbd.KeyIsPressed( 'R' ) ) 57 | { 58 | offset_z += 2.0f * dt; 59 | } 60 | if( kbd.KeyIsPressed( 'F' ) ) 61 | { 62 | offset_z -= 2.0f * dt; 63 | } 64 | } 65 | virtual void Draw() override 66 | { 67 | pipeline.BeginFrame(); 68 | // generate rotation matrix from euler angles 69 | // translation from offset 70 | const Mat3 rot = 71 | Mat3::RotationX( theta_x ) * 72 | Mat3::RotationY( theta_y ) * 73 | Mat3::RotationZ( theta_z ); 74 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 75 | // set pipeline transform 76 | pipeline.effect.vs.BindRotation( rot ); 77 | pipeline.effect.vs.BindTranslation( trans ); 78 | // render triangles 79 | pipeline.Draw( itlist ); 80 | } 81 | private: 82 | IndexedTriangleList itlist; 83 | Pipeline pipeline; 84 | static constexpr float dTheta = PI; 85 | float offset_z = 2.0f; 86 | float theta_x = 0.0f; 87 | float theta_y = 0.0f; 88 | float theta_z = 0.0f; 89 | }; -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Engine/TextureEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | 7 | // basic texture effect 8 | class TextureEffect 9 | { 10 | public: 11 | // the vertex type that will be input into the pipeline 12 | class Vertex 13 | { 14 | public: 15 | Vertex() = default; 16 | Vertex( const Vec3& pos ) 17 | : 18 | pos( pos ) 19 | {} 20 | Vertex( const Vec3& pos,const Vertex& src ) 21 | : 22 | t( src.t ), 23 | pos( pos ) 24 | {} 25 | Vertex( const Vec3& pos,const Vec2& t ) 26 | : 27 | t( t ), 28 | pos( pos ) 29 | {} 30 | Vertex& operator+=( const Vertex& rhs ) 31 | { 32 | pos += rhs.pos; 33 | t += rhs.t; 34 | return *this; 35 | } 36 | Vertex operator+( const Vertex& rhs ) const 37 | { 38 | return Vertex( *this ) += rhs; 39 | } 40 | Vertex& operator-=( const Vertex& rhs ) 41 | { 42 | pos -= rhs.pos; 43 | t -= rhs.t; 44 | return *this; 45 | } 46 | Vertex operator-( const Vertex& rhs ) const 47 | { 48 | return Vertex( *this ) -= rhs; 49 | } 50 | Vertex& operator*=( float rhs ) 51 | { 52 | pos *= rhs; 53 | t *= rhs; 54 | return *this; 55 | } 56 | Vertex operator*( float rhs ) const 57 | { 58 | return Vertex( *this ) *= rhs; 59 | } 60 | Vertex& operator/=( float rhs ) 61 | { 62 | pos /= rhs; 63 | t /= rhs; 64 | return *this; 65 | } 66 | Vertex operator/( float rhs ) const 67 | { 68 | return Vertex( *this ) /= rhs; 69 | } 70 | public: 71 | Vec3 pos; 72 | Vec2 t; 73 | }; 74 | // default vs rotates and translates vertices 75 | // does not touch attributes 76 | typedef DefaultVertexShader VertexShader; 77 | // default gs passes vertices through and outputs triangle 78 | typedef DefaultGeometryShader GeometryShader; 79 | // invoked for each pixel of a triangle 80 | // takes an input of attributes that are the 81 | // result of interpolating vertex attributes 82 | // and outputs a color 83 | class PixelShader 84 | { 85 | public: 86 | template 87 | Color operator()( const Input& in ) const 88 | { 89 | return pTex->GetPixel( 90 | (unsigned int)std::min( in.t.x * tex_width + 0.5f,tex_xclamp ), 91 | (unsigned int)std::min( in.t.y * tex_height + 0.5f,tex_yclamp ) 92 | ); 93 | } 94 | void BindTexture( const std::wstring& filename ) 95 | { 96 | pTex = std::make_unique( Surface::FromFile( filename ) ); 97 | tex_width = float( pTex->GetWidth() ); 98 | tex_height = float( pTex->GetHeight() ); 99 | tex_xclamp = tex_width - 1.0f; 100 | tex_yclamp = tex_height - 1.0f; 101 | } 102 | private: 103 | std::unique_ptr pTex; 104 | float tex_width; 105 | float tex_height; 106 | float tex_xclamp; 107 | float tex_yclamp; 108 | }; 109 | public: 110 | VertexShader vs; 111 | GeometryShader gs; 112 | PixelShader ps; 113 | }; -------------------------------------------------------------------------------- /Engine/DoubleCubeScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "SolidEffect.h" 8 | 9 | class DoubleCubeScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | DoubleCubeScene( Graphics& gfx ) 16 | : 17 | itlist( Cube::GetPlainIndependentFaces() ), 18 | pipeline( gfx ), 19 | Scene( "Double cube interpenetration test scene" ) 20 | { 21 | const Color colors[] = { 22 | Colors::Red,Colors::Green,Colors::Blue,Colors::Magenta,Colors::Yellow,Colors::Cyan 23 | }; 24 | 25 | for( int i = 0; i < itlist.vertices.size(); i++ ) 26 | { 27 | itlist.vertices[i].color = colors[i / 4]; 28 | } 29 | } 30 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 31 | { 32 | if( kbd.KeyIsPressed( 'Q' ) ) 33 | { 34 | theta_x = wrap_angle( theta_x + dTheta * dt ); 35 | } 36 | if( kbd.KeyIsPressed( 'W' ) ) 37 | { 38 | theta_y = wrap_angle( theta_y + dTheta * dt ); 39 | } 40 | if( kbd.KeyIsPressed( 'E' ) ) 41 | { 42 | theta_z = wrap_angle( theta_z + dTheta * dt ); 43 | } 44 | if( kbd.KeyIsPressed( 'A' ) ) 45 | { 46 | theta_x = wrap_angle( theta_x - dTheta * dt ); 47 | } 48 | if( kbd.KeyIsPressed( 'S' ) ) 49 | { 50 | theta_y = wrap_angle( theta_y - dTheta * dt ); 51 | } 52 | if( kbd.KeyIsPressed( 'D' ) ) 53 | { 54 | theta_z = wrap_angle( theta_z - dTheta * dt ); 55 | } 56 | if( kbd.KeyIsPressed( 'R' ) ) 57 | { 58 | offset_z += 2.0f * dt; 59 | } 60 | if( kbd.KeyIsPressed( 'F' ) ) 61 | { 62 | offset_z -= 2.0f * dt; 63 | } 64 | } 65 | virtual void Draw() override 66 | { 67 | pipeline.BeginFrame(); 68 | // draw fixed cube 69 | { 70 | // generate rotation matrix from euler angles 71 | // rotate in opposition to mobile cube 72 | const Mat3 rot = 73 | Mat3::RotationX( -theta_x ) * 74 | Mat3::RotationY( -theta_y ) * 75 | Mat3::RotationZ( -theta_z ); 76 | // set pipeline transform 77 | pipeline.effect.vs.BindRotation( rot ); 78 | pipeline.effect.vs.BindTranslation( { 0.0f,0.0f,2.0f } ); 79 | // render triangles 80 | pipeline.Draw( itlist ); 81 | } 82 | // draw mobile cube 83 | { 84 | // generate rotation matrix from euler angles 85 | const Mat3 rot = 86 | Mat3::RotationX( theta_x ) * 87 | Mat3::RotationY( theta_y ) * 88 | Mat3::RotationZ( theta_z ); 89 | // set pipeline transform 90 | pipeline.effect.vs.BindRotation( rot ); 91 | pipeline.effect.vs.BindTranslation( { 0.0f,0.0f,offset_z } ); 92 | // render triangles 93 | pipeline.Draw( itlist ); 94 | } 95 | } 96 | private: 97 | IndexedTriangleList itlist; 98 | Pipeline pipeline; 99 | static constexpr float dTheta = PI; 100 | float offset_z = 2.0f; 101 | float theta_x = 0.0f; 102 | float theta_y = 0.0f; 103 | float theta_z = 0.0f; 104 | }; -------------------------------------------------------------------------------- /Engine/Keyboard.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Keyboard.h * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include 23 | #include 24 | 25 | class Keyboard 26 | { 27 | friend class MainWindow; 28 | public: 29 | class Event 30 | { 31 | public: 32 | enum Type 33 | { 34 | Press, 35 | Release, 36 | Invalid 37 | }; 38 | private: 39 | Type type; 40 | unsigned char code; 41 | public: 42 | Event() 43 | : 44 | type( Invalid ), 45 | code( 0u ) 46 | {} 47 | Event( Type type,unsigned char code ) 48 | : 49 | type( type ), 50 | code( code ) 51 | {} 52 | bool IsPress() const 53 | { 54 | return type == Press; 55 | } 56 | bool IsRelease() const 57 | { 58 | return type == Release; 59 | } 60 | bool IsValid() const 61 | { 62 | return type != Invalid; 63 | } 64 | unsigned char GetCode() const 65 | { 66 | return code; 67 | } 68 | }; 69 | public: 70 | Keyboard() = default; 71 | Keyboard( const Keyboard& ) = delete; 72 | Keyboard& operator=( const Keyboard& ) = delete; 73 | bool KeyIsPressed( unsigned char keycode ) const; 74 | Event ReadKey(); 75 | bool KeyIsEmpty() const; 76 | char ReadChar(); 77 | bool CharIsEmpty() const; 78 | void FlushKey(); 79 | void FlushChar(); 80 | void Flush(); 81 | void EnableAutorepeat(); 82 | void DisableAutorepeat(); 83 | bool AutorepeatIsEnabled() const; 84 | private: 85 | void OnKeyPressed( unsigned char keycode ); 86 | void OnKeyReleased( unsigned char keycode ); 87 | void OnChar( char character ); 88 | template 89 | void TrimBuffer( std::queue& buffer ); 90 | private: 91 | static constexpr unsigned int nKeys = 256u; 92 | static constexpr unsigned int bufferSize = 4u; 93 | bool autorepeatEnabled = false; 94 | std::bitset keystates; 95 | std::queue keybuffer; 96 | std::queue charbuffer; 97 | }; -------------------------------------------------------------------------------- /Engine/Sphere.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Vec3.h" 4 | #include "Mat.h" 5 | #include "IndexedTriangleList.h" 6 | 7 | class Sphere 8 | { 9 | public: 10 | template 11 | static IndexedTriangleList GetPlain( float radius = 1.0f,int latDiv = 12,int longDiv = 24 ) 12 | { 13 | const Vec3 base = { 0.0f,0.0f,radius }; 14 | const float lattitudeAngle = PI / latDiv; 15 | const float longitudeAngle = 2.0f * PI / longDiv; 16 | 17 | std::vector vertices; 18 | for( int iLat = 1; iLat < latDiv; iLat++ ) 19 | { 20 | const auto latBase = base * Mat3::RotationX( lattitudeAngle * iLat ); 21 | for( int iLong = 0; iLong < longDiv; iLong++ ) 22 | { 23 | vertices.emplace_back(); 24 | vertices.back().pos = latBase * Mat3::RotationZ( longitudeAngle * iLong ); 25 | } 26 | } 27 | 28 | // add the cap vertices 29 | const auto iNorthPole = vertices.size(); 30 | vertices.emplace_back(); 31 | vertices.back().pos = base; 32 | const auto iSouthPole = vertices.size(); 33 | vertices.emplace_back(); 34 | vertices.back().pos = -base; 35 | 36 | const auto calcIdx = [latDiv,longDiv]( int iLat,int iLong ) 37 | { return iLat * longDiv + iLong; }; 38 | std::vector indices; 39 | for( int iLat = 0; iLat < latDiv - 2; iLat++ ) 40 | { 41 | for( int iLong = 0; iLong < longDiv - 1; iLong++ ) 42 | { 43 | indices.push_back( calcIdx( iLat,iLong ) ); 44 | indices.push_back( calcIdx( iLat + 1,iLong ) ); 45 | indices.push_back( calcIdx( iLat,iLong + 1 ) ); 46 | indices.push_back( calcIdx( iLat,iLong + 1 ) ); 47 | indices.push_back( calcIdx( iLat + 1,iLong ) ); 48 | indices.push_back( calcIdx( iLat + 1,iLong + 1 ) ); 49 | } 50 | // wrap band 51 | indices.push_back( calcIdx( iLat,longDiv - 1 ) ); 52 | indices.push_back( calcIdx( iLat + 1,longDiv - 1 ) ); 53 | indices.push_back( calcIdx( iLat,0 ) ); 54 | indices.push_back( calcIdx( iLat,0 ) ); 55 | indices.push_back( calcIdx( iLat + 1,longDiv - 1 ) ); 56 | indices.push_back( calcIdx( iLat + 1,0 ) ); 57 | } 58 | 59 | // cap fans 60 | for( int iLong = 0; iLong < longDiv - 1; iLong++ ) 61 | { 62 | // north 63 | indices.push_back( iNorthPole ); 64 | indices.push_back( calcIdx( 0,iLong ) ); 65 | indices.push_back( calcIdx( 0,iLong + 1 ) ); 66 | // south 67 | indices.push_back( calcIdx( latDiv - 2,iLong + 1 ) ); 68 | indices.push_back( calcIdx( latDiv - 2,iLong ) ); 69 | indices.push_back( iSouthPole ); 70 | } 71 | // wrap triangles 72 | // north 73 | indices.push_back( iNorthPole ); 74 | indices.push_back( calcIdx( 0,longDiv - 1 ) ); 75 | indices.push_back( calcIdx( 0,0 ) ); 76 | // south 77 | indices.push_back( calcIdx( latDiv - 2,0 ) ); 78 | indices.push_back( calcIdx( latDiv - 2,longDiv - 1 ) ); 79 | indices.push_back( iSouthPole ); 80 | 81 | 82 | return{ std::move( vertices ),std::move( indices ) }; 83 | } 84 | template 85 | static IndexedTriangleList GetPlainNormals( float radius = 1.0f,int latDiv = 12,int longDiv = 24 ) 86 | { 87 | auto sphere = GetPlain( radius,latDiv,longDiv ); 88 | for( auto& v : sphere.vertices ) 89 | { 90 | v.n = v.pos.GetNormalized(); 91 | } 92 | return sphere; 93 | } 94 | }; -------------------------------------------------------------------------------- /Engine/CubeFlatIndependentScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "VertexFlatEffect.h" 8 | 9 | class CubeFlatIndependentScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | CubeFlatIndependentScene( Graphics& gfx ) 16 | : 17 | itlist( Cube::GetIndependentFacesNormals() ), 18 | pipeline( gfx ), 19 | Scene( "Cube flat vertex scene" ) 20 | {} 21 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 22 | { 23 | if( kbd.KeyIsPressed( 'Q' ) ) 24 | { 25 | theta_x = wrap_angle( theta_x + dTheta * dt ); 26 | } 27 | if( kbd.KeyIsPressed( 'W' ) ) 28 | { 29 | theta_y = wrap_angle( theta_y + dTheta * dt ); 30 | } 31 | if( kbd.KeyIsPressed( 'E' ) ) 32 | { 33 | theta_z = wrap_angle( theta_z + dTheta * dt ); 34 | } 35 | if( kbd.KeyIsPressed( 'A' ) ) 36 | { 37 | theta_x = wrap_angle( theta_x - dTheta * dt ); 38 | } 39 | if( kbd.KeyIsPressed( 'S' ) ) 40 | { 41 | theta_y = wrap_angle( theta_y - dTheta * dt ); 42 | } 43 | if( kbd.KeyIsPressed( 'D' ) ) 44 | { 45 | theta_z = wrap_angle( theta_z - dTheta * dt ); 46 | } 47 | if( kbd.KeyIsPressed( 'U' ) ) 48 | { 49 | phi_x = wrap_angle( phi_x + dTheta * dt ); 50 | } 51 | if( kbd.KeyIsPressed( 'I' ) ) 52 | { 53 | phi_y = wrap_angle( phi_y + dTheta * dt ); 54 | } 55 | if( kbd.KeyIsPressed( 'O' ) ) 56 | { 57 | phi_z = wrap_angle( phi_z + dTheta * dt ); 58 | } 59 | if( kbd.KeyIsPressed( 'J' ) ) 60 | { 61 | phi_x = wrap_angle( phi_x - dTheta * dt ); 62 | } 63 | if( kbd.KeyIsPressed( 'K' ) ) 64 | { 65 | phi_y = wrap_angle( phi_y - dTheta * dt ); 66 | } 67 | if( kbd.KeyIsPressed( 'L' ) ) 68 | { 69 | phi_z = wrap_angle( phi_z - dTheta * dt ); 70 | } 71 | if( kbd.KeyIsPressed( 'R' ) ) 72 | { 73 | offset_z += 0.2f * dt; 74 | } 75 | if( kbd.KeyIsPressed( 'F' ) ) 76 | { 77 | offset_z -= 0.2f * dt; 78 | } 79 | } 80 | virtual void Draw() override 81 | { 82 | pipeline.BeginFrame(); 83 | // generate rotation matrix from euler angles 84 | // translation from offset 85 | const Mat3 rot = 86 | Mat3::RotationX( theta_x ) * 87 | Mat3::RotationY( theta_y ) * 88 | Mat3::RotationZ( theta_z ); 89 | const Mat3 rot_phi = 90 | Mat3::RotationX( phi_x ) * 91 | Mat3::RotationY( phi_y ) * 92 | Mat3::RotationZ( phi_z ); 93 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 94 | // set pipeline transform 95 | pipeline.effect.vs.BindRotation( rot ); 96 | pipeline.effect.vs.BindTranslation( trans ); 97 | pipeline.effect.vs.SetLightDirection( light_dir * rot_phi ); 98 | // render triangles 99 | pipeline.Draw( itlist ); 100 | } 101 | private: 102 | IndexedTriangleList itlist; 103 | Pipeline pipeline; 104 | static constexpr float dTheta = PI; 105 | float offset_z = 2.0f; 106 | float theta_x = 0.0f; 107 | float theta_y = 0.0f; 108 | float theta_z = 0.0f; 109 | float phi_x = 0.0f; 110 | float phi_y = 0.0f; 111 | float phi_z = 0.0f; 112 | Vec3 light_dir = { 0.2f,-0.5f,1.0f }; 113 | }; -------------------------------------------------------------------------------- /Engine/MainWindow.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * MainWindow.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include "ChiliWin.h" 23 | #include "Graphics.h" 24 | #include "Keyboard.h" 25 | #include "Mouse.h" 26 | #include "ChiliException.h" 27 | #include 28 | 29 | // for granting special access to hWnd only for Graphics constructor 30 | class HWNDKey 31 | { 32 | friend Graphics::Graphics( HWNDKey& ); 33 | public: 34 | HWNDKey( const HWNDKey& ) = delete; 35 | HWNDKey& operator=( HWNDKey& ) = delete; 36 | protected: 37 | HWNDKey() = default; 38 | protected: 39 | HWND hWnd = nullptr; 40 | }; 41 | 42 | class MainWindow : public HWNDKey 43 | { 44 | public: 45 | class Exception : public ChiliException 46 | { 47 | public: 48 | using ChiliException::ChiliException; 49 | virtual std::wstring GetFullMessage() const override { return GetNote() + L"\nAt: " + GetLocation(); } 50 | virtual std::wstring GetExceptionType() const override { return L"Windows Exception"; } 51 | }; 52 | public: 53 | MainWindow( HINSTANCE hInst,wchar_t* pArgs ); 54 | MainWindow( const MainWindow& ) = delete; 55 | MainWindow& operator=( const MainWindow& ) = delete; 56 | ~MainWindow(); 57 | bool IsActive() const; 58 | bool IsMinimized() const; 59 | void ShowMessageBox( const std::wstring& title,const std::wstring& message ) const; 60 | void Kill() 61 | { 62 | PostQuitMessage( 0 ); 63 | } 64 | // returns false if quitting 65 | bool ProcessMessage(); 66 | const std::wstring& GetArgs() const 67 | { 68 | return args; 69 | } 70 | private: 71 | static LRESULT WINAPI _HandleMsgSetup( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ); 72 | static LRESULT WINAPI _HandleMsgThunk( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ); 73 | LRESULT HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ); 74 | public: 75 | Keyboard kbd; 76 | Mouse mouse; 77 | private: 78 | static constexpr const wchar_t* wndClassName = L"Chili DirectX Framework Window"; 79 | HINSTANCE hInst = nullptr; 80 | std::wstring args; 81 | }; -------------------------------------------------------------------------------- /Engine/GouraudScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "GouraudEffect.h" 8 | 9 | class GouraudScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | GouraudScene( Graphics& gfx,IndexedTriangleList tl ) 16 | : 17 | itlist( std::move( tl ) ), 18 | pipeline( gfx ), 19 | Scene( "gouraud shader scene free mesh" ) 20 | { 21 | itlist.AdjustToTrueCenter(); 22 | offset_z = itlist.GetRadius() * 1.6f; 23 | } 24 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 25 | { 26 | if( kbd.KeyIsPressed( 'Q' ) ) 27 | { 28 | theta_x = wrap_angle( theta_x + dTheta * dt ); 29 | } 30 | if( kbd.KeyIsPressed( 'W' ) ) 31 | { 32 | theta_y = wrap_angle( theta_y + dTheta * dt ); 33 | } 34 | if( kbd.KeyIsPressed( 'E' ) ) 35 | { 36 | theta_z = wrap_angle( theta_z + dTheta * dt ); 37 | } 38 | if( kbd.KeyIsPressed( 'A' ) ) 39 | { 40 | theta_x = wrap_angle( theta_x - dTheta * dt ); 41 | } 42 | if( kbd.KeyIsPressed( 'S' ) ) 43 | { 44 | theta_y = wrap_angle( theta_y - dTheta * dt ); 45 | } 46 | if( kbd.KeyIsPressed( 'D' ) ) 47 | { 48 | theta_z = wrap_angle( theta_z - dTheta * dt ); 49 | } 50 | if( kbd.KeyIsPressed( 'U' ) ) 51 | { 52 | phi_x = wrap_angle( phi_x + dTheta * dt ); 53 | } 54 | if( kbd.KeyIsPressed( 'I' ) ) 55 | { 56 | phi_y = wrap_angle( phi_y + dTheta * dt ); 57 | } 58 | if( kbd.KeyIsPressed( 'O' ) ) 59 | { 60 | phi_z = wrap_angle( phi_z + dTheta * dt ); 61 | } 62 | if( kbd.KeyIsPressed( 'J' ) ) 63 | { 64 | phi_x = wrap_angle( phi_x - dTheta * dt ); 65 | } 66 | if( kbd.KeyIsPressed( 'K' ) ) 67 | { 68 | phi_y = wrap_angle( phi_y - dTheta * dt ); 69 | } 70 | if( kbd.KeyIsPressed( 'L' ) ) 71 | { 72 | phi_z = wrap_angle( phi_z - dTheta * dt ); 73 | } 74 | if( kbd.KeyIsPressed( 'R' ) ) 75 | { 76 | offset_z += 0.2f * dt; 77 | } 78 | if( kbd.KeyIsPressed( 'F' ) ) 79 | { 80 | offset_z -= 0.2f * dt; 81 | } 82 | } 83 | virtual void Draw() override 84 | { 85 | pipeline.BeginFrame(); 86 | // generate rotation matrix from euler angles 87 | // translation from offset 88 | const Mat3 rot = 89 | Mat3::RotationX( theta_x ) * 90 | Mat3::RotationY( theta_y ) * 91 | Mat3::RotationZ( theta_z ); 92 | const Mat3 rot_phi = 93 | Mat3::RotationX( phi_x ) * 94 | Mat3::RotationY( phi_y ) * 95 | Mat3::RotationZ( phi_z ); 96 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 97 | // set pipeline transform 98 | pipeline.effect.vs.BindRotation( rot ); 99 | pipeline.effect.vs.BindTranslation( trans ); 100 | pipeline.effect.vs.SetLightDirection( light_dir * rot_phi ); 101 | // render triangles 102 | pipeline.Draw( itlist ); 103 | } 104 | private: 105 | IndexedTriangleList itlist; 106 | Pipeline pipeline; 107 | static constexpr float dTheta = PI; 108 | float offset_z = 2.0f; 109 | float theta_x = 0.0f; 110 | float theta_y = 0.0f; 111 | float theta_z = 0.0f; 112 | float phi_x = 0.0f; 113 | float phi_y = 0.0f; 114 | float phi_z = 0.0f; 115 | Vec3 light_dir = { 0.2f,-0.5f,1.0f }; 116 | }; -------------------------------------------------------------------------------- /Engine/Main.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Main.cpp * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #include "MainWindow.h" 22 | #include "Game.h" 23 | #include "ChiliException.h" 24 | #include "Mat.h" 25 | 26 | int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR pArgs,INT ) 27 | { 28 | try 29 | { 30 | MainWindow wnd( hInst,pArgs ); 31 | try 32 | { 33 | Game theGame( wnd ); 34 | while( wnd.ProcessMessage() ) 35 | { 36 | theGame.Go(); 37 | } 38 | } 39 | catch( const ChiliException& e ) 40 | { 41 | const std::wstring eMsg = e.GetFullMessage() + 42 | L"\n\nException caught at Windows message loop."; 43 | wnd.ShowMessageBox( e.GetExceptionType(),eMsg ); 44 | } 45 | catch( const std::exception& e ) 46 | { 47 | // need to convert std::exception what() string from narrow to wide string 48 | const std::string whatStr( e.what() ); 49 | const std::wstring eMsg = std::wstring( whatStr.begin(),whatStr.end() ) + 50 | L"\n\nException caught at Windows message loop."; 51 | wnd.ShowMessageBox( L"Unhandled STL Exception",eMsg ); 52 | } 53 | catch( ... ) 54 | { 55 | wnd.ShowMessageBox( L"Unhandled Non-STL Exception", 56 | L"\n\nException caught at Windows message loop." ); 57 | } 58 | } 59 | catch( const ChiliException& e ) 60 | { 61 | const std::wstring eMsg = e.GetFullMessage() + 62 | L"\n\nException caught at main window creation."; 63 | MessageBox( nullptr,eMsg.c_str(),e.GetExceptionType().c_str(),MB_OK ); 64 | } 65 | catch( const std::exception& e ) 66 | { 67 | // need to convert std::exception what() string from narrow to wide string 68 | const std::string whatStr( e.what() ); 69 | const std::wstring eMsg = std::wstring( whatStr.begin(),whatStr.end() ) + 70 | L"\n\nException caught at main window creation."; 71 | MessageBox( nullptr,eMsg.c_str(),L"Unhandled STL Exception",MB_OK ); 72 | } 73 | catch( ... ) 74 | { 75 | MessageBox( nullptr,L"\n\nException caught at main window creation.", 76 | L"Unhandled Non-STL Exception",MB_OK ); 77 | } 78 | 79 | return 0; 80 | } -------------------------------------------------------------------------------- /Engine/GeometryFlatScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "GeometryFlatEffect.h" 8 | 9 | class GeometryFlatScene : public Scene 10 | { 11 | public: 12 | typedef Pipeline Pipeline; 13 | typedef Pipeline::Vertex Vertex; 14 | public: 15 | GeometryFlatScene( Graphics& gfx,IndexedTriangleList tl ) 16 | : 17 | itlist( std::move( tl ) ), 18 | pipeline( gfx ), 19 | Scene( "flat geometry scene free mesh" ) 20 | { 21 | itlist.AdjustToTrueCenter(); 22 | offset_z = itlist.GetRadius() * 1.6f; 23 | } 24 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 25 | { 26 | if( kbd.KeyIsPressed( 'Q' ) ) 27 | { 28 | theta_x = wrap_angle( theta_x + dTheta * dt ); 29 | } 30 | if( kbd.KeyIsPressed( 'W' ) ) 31 | { 32 | theta_y = wrap_angle( theta_y + dTheta * dt ); 33 | } 34 | if( kbd.KeyIsPressed( 'E' ) ) 35 | { 36 | theta_z = wrap_angle( theta_z + dTheta * dt ); 37 | } 38 | if( kbd.KeyIsPressed( 'A' ) ) 39 | { 40 | theta_x = wrap_angle( theta_x - dTheta * dt ); 41 | } 42 | if( kbd.KeyIsPressed( 'S' ) ) 43 | { 44 | theta_y = wrap_angle( theta_y - dTheta * dt ); 45 | } 46 | if( kbd.KeyIsPressed( 'D' ) ) 47 | { 48 | theta_z = wrap_angle( theta_z - dTheta * dt ); 49 | } 50 | if( kbd.KeyIsPressed( 'U' ) ) 51 | { 52 | phi_x = wrap_angle( phi_x + dTheta * dt ); 53 | } 54 | if( kbd.KeyIsPressed( 'I' ) ) 55 | { 56 | phi_y = wrap_angle( phi_y + dTheta * dt ); 57 | } 58 | if( kbd.KeyIsPressed( 'O' ) ) 59 | { 60 | phi_z = wrap_angle( phi_z + dTheta * dt ); 61 | } 62 | if( kbd.KeyIsPressed( 'J' ) ) 63 | { 64 | phi_x = wrap_angle( phi_x - dTheta * dt ); 65 | } 66 | if( kbd.KeyIsPressed( 'K' ) ) 67 | { 68 | phi_y = wrap_angle( phi_y - dTheta * dt ); 69 | } 70 | if( kbd.KeyIsPressed( 'L' ) ) 71 | { 72 | phi_z = wrap_angle( phi_z - dTheta * dt ); 73 | } 74 | if( kbd.KeyIsPressed( 'R' ) ) 75 | { 76 | offset_z += 0.2f * dt; 77 | } 78 | if( kbd.KeyIsPressed( 'F' ) ) 79 | { 80 | offset_z -= 0.2f * dt; 81 | } 82 | } 83 | virtual void Draw() override 84 | { 85 | pipeline.BeginFrame(); 86 | // generate rotation matrix from euler angles 87 | // translation from offset 88 | const Mat3 rot = 89 | Mat3::RotationX( theta_x ) * 90 | Mat3::RotationY( theta_y ) * 91 | Mat3::RotationZ( theta_z ); 92 | const Mat3 rot_phi = 93 | Mat3::RotationX( phi_x ) * 94 | Mat3::RotationY( phi_y ) * 95 | Mat3::RotationZ( phi_z ); 96 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 97 | // set pipeline transform 98 | pipeline.effect.vs.BindRotation( rot ); 99 | pipeline.effect.vs.BindTranslation( trans ); 100 | pipeline.effect.gs.SetLightDirection( light_dir * rot_phi ); 101 | // render triangles 102 | pipeline.Draw( itlist ); 103 | } 104 | private: 105 | IndexedTriangleList itlist; 106 | Pipeline pipeline; 107 | static constexpr float dTheta = PI; 108 | float offset_z = 2.0f; 109 | float theta_x = 0.0f; 110 | float theta_y = 0.0f; 111 | float theta_z = 0.0f; 112 | float phi_x = 0.0f; 113 | float phi_y = 0.0f; 114 | float phi_z = 0.0f; 115 | Vec3 light_dir = { 0.2f,-0.5f,1.0f }; 116 | }; -------------------------------------------------------------------------------- /Engine/DXErr.h: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------------------------------- 2 | // File: DXErr.h 3 | // 4 | // DirectX Error Library 5 | // 6 | // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 7 | // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 8 | // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 9 | // PARTICULAR PURPOSE. 10 | // 11 | // Copyright (c) Microsoft Corporation. All rights reserved. 12 | //-------------------------------------------------------------------------------------- 13 | 14 | // This version only supports UNICODE. 15 | 16 | #pragma once 17 | 18 | #include "ChiliWin.h" 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | //-------------------------------------------------------------------------------------- 26 | // DXGetErrorString 27 | //-------------------------------------------------------------------------------------- 28 | const WCHAR* WINAPI DXGetErrorStringW( _In_ HRESULT hr ); 29 | 30 | #define DXGetErrorString DXGetErrorStringW 31 | 32 | //-------------------------------------------------------------------------------------- 33 | // DXGetErrorDescription has to be modified to return a copy in a buffer rather than 34 | // the original static string. 35 | //-------------------------------------------------------------------------------------- 36 | void WINAPI DXGetErrorDescriptionW( _In_ HRESULT hr, _Out_cap_(count) WCHAR* desc, _In_ size_t count ); 37 | 38 | #define DXGetErrorDescription DXGetErrorDescriptionW 39 | 40 | //-------------------------------------------------------------------------------------- 41 | // DXTrace 42 | // 43 | // Desc: Outputs a formatted error message to the debug stream 44 | // 45 | // Args: WCHAR* strFile The current file, typically passed in using the 46 | // __FILEW__ macro. 47 | // DWORD dwLine The current line number, typically passed in using the 48 | // __LINE__ macro. 49 | // HRESULT hr An HRESULT that will be traced to the debug stream. 50 | // CHAR* strMsg A string that will be traced to the debug stream (may be NULL) 51 | // BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info. 52 | // 53 | // Return: The hr that was passed in. 54 | //-------------------------------------------------------------------------------------- 55 | HRESULT WINAPI DXTraceW( _In_z_ const WCHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr, _In_opt_ const WCHAR* strMsg, _In_ bool bPopMsgBox ); 56 | 57 | #define DXTrace DXTraceW 58 | 59 | //-------------------------------------------------------------------------------------- 60 | // 61 | // Helper macros 62 | // 63 | //-------------------------------------------------------------------------------------- 64 | #if defined(DEBUG) || defined(_DEBUG) 65 | #define DXTRACE_MSG(str) DXTrace( __FILEW__, (DWORD)__LINE__, 0, str, false ) 66 | #define DXTRACE_ERR(str,hr) DXTrace( __FILEW__, (DWORD)__LINE__, hr, str, false ) 67 | #define DXTRACE_ERR_MSGBOX(str,hr) DXTrace( __FILEW__, (DWORD)__LINE__, hr, str, true ) 68 | #else 69 | #define DXTRACE_MSG(str) (0L) 70 | #define DXTRACE_ERR(str,hr) (hr) 71 | #define DXTRACE_ERR_MSGBOX(str,hr) (hr) 72 | #endif 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif //__cplusplus 77 | -------------------------------------------------------------------------------- /Engine/VertexWaveScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma once 4 | 5 | #pragma once 6 | 7 | #include "Scene.h" 8 | #include "Plane.h" 9 | #include "Mat.h" 10 | #include "WaveVertexTextureEffect.h" 11 | 12 | class VertexWaveScene : public Scene 13 | { 14 | public: 15 | typedef Pipeline Pipeline; 16 | typedef Pipeline::Vertex Vertex; 17 | public: 18 | VertexWaveScene( Graphics& gfx ) 19 | : 20 | itlist( Plane::GetSkinned( 20 ) ), 21 | pipeline( gfx ), 22 | Scene( "Test Plane Rippling VS" ) 23 | { 24 | pipeline.effect.ps.BindTexture( L"images\\sauron-bhole-100x100.png" ); 25 | } 26 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 27 | { 28 | if( kbd.KeyIsPressed( 'Q' ) ) 29 | { 30 | theta_x = wrap_angle( theta_x + dTheta * dt ); 31 | } 32 | if( kbd.KeyIsPressed( 'W' ) ) 33 | { 34 | theta_y = wrap_angle( theta_y + dTheta * dt ); 35 | } 36 | if( kbd.KeyIsPressed( 'E' ) ) 37 | { 38 | theta_z = wrap_angle( theta_z + dTheta * dt ); 39 | } 40 | if( kbd.KeyIsPressed( 'A' ) ) 41 | { 42 | theta_x = wrap_angle( theta_x - dTheta * dt ); 43 | } 44 | if( kbd.KeyIsPressed( 'S' ) ) 45 | { 46 | theta_y = wrap_angle( theta_y - dTheta * dt ); 47 | } 48 | if( kbd.KeyIsPressed( 'D' ) ) 49 | { 50 | theta_z = wrap_angle( theta_z - dTheta * dt ); 51 | } 52 | if( kbd.KeyIsPressed( 'U' ) ) 53 | { 54 | phi_x = wrap_angle( phi_x + dTheta * dt ); 55 | } 56 | if( kbd.KeyIsPressed( 'I' ) ) 57 | { 58 | phi_y = wrap_angle( phi_y + dTheta * dt ); 59 | } 60 | if( kbd.KeyIsPressed( 'O' ) ) 61 | { 62 | phi_z = wrap_angle( phi_z + dTheta * dt ); 63 | } 64 | if( kbd.KeyIsPressed( 'J' ) ) 65 | { 66 | phi_x = wrap_angle( phi_x - dTheta * dt ); 67 | } 68 | if( kbd.KeyIsPressed( 'K' ) ) 69 | { 70 | phi_y = wrap_angle( phi_y - dTheta * dt ); 71 | } 72 | if( kbd.KeyIsPressed( 'L' ) ) 73 | { 74 | phi_z = wrap_angle( phi_z - dTheta * dt ); 75 | } 76 | if( kbd.KeyIsPressed( 'R' ) ) 77 | { 78 | offset_z += 2.0f * dt; 79 | } 80 | if( kbd.KeyIsPressed( 'F' ) ) 81 | { 82 | offset_z -= 2.0f * dt; 83 | } 84 | time += dt; 85 | } 86 | virtual void Draw() override 87 | { 88 | pipeline.BeginFrame(); 89 | // generate rotation matrix from euler angles 90 | // translation from offset 91 | const Mat3 rot = 92 | Mat3::RotationX( theta_x ) * 93 | Mat3::RotationY( theta_y ) * 94 | Mat3::RotationZ( theta_z ); 95 | const Mat3 rot_phi = 96 | Mat3::RotationX( phi_x ) * 97 | Mat3::RotationY( phi_y ) * 98 | Mat3::RotationZ( phi_z ); 99 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 100 | // set pipeline transform 101 | pipeline.effect.vs.BindRotation( rot ); 102 | pipeline.effect.vs.BindTranslation( trans ); 103 | pipeline.effect.vs.SetTime( time ); 104 | pipeline.effect.gs.SetLightDirection( light_dir * rot_phi ); 105 | // render triangles 106 | pipeline.Draw( itlist ); 107 | } 108 | private: 109 | IndexedTriangleList itlist; 110 | Pipeline pipeline; 111 | static constexpr float dTheta = PI; 112 | float offset_z = 2.0f; 113 | float theta_x = 0.0f; 114 | float theta_y = 0.0f; 115 | float theta_z = 0.0f; 116 | float time = 0.0f; 117 | float phi_x = 0.0f; 118 | float phi_y = 0.0f; 119 | float phi_z = 0.0f; 120 | Vec3 light_dir = { 0.2f,-0.5f,1.0f }; 121 | }; -------------------------------------------------------------------------------- /Engine/Rect.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Rect.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include "Vec2.h" 24 | #include 25 | 26 | template < typename T > 27 | class _Rect 28 | { 29 | public: 30 | inline _Rect() {} 31 | inline _Rect( T top,T bottom,T left,T right ) 32 | : 33 | top( top ), 34 | bottom( bottom ), 35 | left( left ), 36 | right( right ) 37 | {} 38 | inline _Rect( const _Rect& rect ) 39 | : 40 | top( rect.top ), 41 | bottom( rect.bottom ), 42 | left( rect.left ), 43 | right( rect.right ) 44 | {} 45 | inline _Rect( _Vec2 p0,_Vec2 p1 ) 46 | : 47 | _Rect( min( p0.y,p1.y ), 48 | max( p0.y,p1.y ), 49 | min( p0.x,p1.x ), 50 | max( p0.x,p1.x ) ) 51 | {} 52 | inline void Translate( _Vec2 d ) 53 | { 54 | Translate( d.x,d.y ); 55 | } 56 | inline void Translate( T dx,T dy ) 57 | { 58 | top += dy; 59 | bottom += dy; 60 | left += dx; 61 | right += dx; 62 | } 63 | template 64 | inline operator _Rect() const 65 | { 66 | return { (T2)top,(T2)bottom,(T2)left,(T2)right }; 67 | } 68 | inline void ClipTo( const _Rect& rect ) 69 | { 70 | top = std::max( top,rect.top ); 71 | bottom = std::min( bottom,rect.bottom ); 72 | left = std::max( left,rect.left ); 73 | right = std::min( right,rect.right ); 74 | } 75 | inline T GetWidth() const 76 | { 77 | return right - left; 78 | } 79 | inline T GetHeight() const 80 | { 81 | return bottom - top; 82 | } 83 | inline bool Overlaps( const _Rect& rect ) const 84 | { 85 | return top < rect.bottom && bottom > rect.top && 86 | left < rect.right && right > rect.left; 87 | } 88 | template 89 | inline bool Contains( _Vec2 p ) const 90 | { 91 | return p.y >= top && p.y <= bottom && p.x >= left && p.x <= right; 92 | } 93 | template 94 | inline bool Contains( _Rect p ) const 95 | { 96 | return p.top >= top && p.bottom <= bottom && p.left >= left && p.right <= right; 97 | } 98 | public: 99 | T top; 100 | T bottom; 101 | T left; 102 | T right; 103 | }; 104 | 105 | typedef _Rect< int > RectI; 106 | typedef _Rect< float > RectF; -------------------------------------------------------------------------------- /Engine/SpecularPhongPointEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "BaseVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | #include "BasePhongShader.h" 7 | 8 | // flat shading with vertex normals 9 | template 10 | class SpecularPhongPointEffect 11 | { 12 | public: 13 | // the vertex type that will be input into the pipeline 14 | class Vertex 15 | { 16 | public: 17 | Vertex() = default; 18 | Vertex( const Vec3& pos ) 19 | : 20 | pos( pos ) 21 | {} 22 | Vertex( const Vec3& pos,const Vertex& src ) 23 | : 24 | n( src.n ), 25 | pos( pos ) 26 | {} 27 | Vertex( const Vec3& pos,const Vec3& n ) 28 | : 29 | n( n ), 30 | pos( pos ) 31 | {} 32 | public: 33 | Vec3 pos; 34 | Vec3 n; 35 | }; 36 | // vertex shader 37 | // output interpolates position, normal, world position 38 | class VSOutput 39 | { 40 | public: 41 | VSOutput() = default; 42 | VSOutput( const Vec4& pos ) 43 | : 44 | pos( pos ) 45 | {} 46 | VSOutput( const Vec4& pos,const VSOutput& src ) 47 | : 48 | n( src.n ), 49 | worldPos( src.worldPos ), 50 | pos( pos ) 51 | {} 52 | VSOutput( const Vec4& pos,const Vec3& n,const Vec3& worldPos ) 53 | : 54 | n( n ), 55 | pos( pos ), 56 | worldPos( worldPos ) 57 | {} 58 | VSOutput& operator+=( const VSOutput& rhs ) 59 | { 60 | pos += rhs.pos; 61 | n += rhs.n; 62 | worldPos += rhs.worldPos; 63 | return *this; 64 | } 65 | VSOutput operator+( const VSOutput& rhs ) const 66 | { 67 | return VSOutput( *this ) += rhs; 68 | } 69 | VSOutput& operator-=( const VSOutput& rhs ) 70 | { 71 | pos -= rhs.pos; 72 | n -= rhs.n; 73 | worldPos -= rhs.worldPos; 74 | return *this; 75 | } 76 | VSOutput operator-( const VSOutput& rhs ) const 77 | { 78 | return VSOutput( *this ) -= rhs; 79 | } 80 | VSOutput& operator*=( float rhs ) 81 | { 82 | pos *= rhs; 83 | n *= rhs; 84 | worldPos *= rhs; 85 | return *this; 86 | } 87 | VSOutput operator*( float rhs ) const 88 | { 89 | return VSOutput( *this ) *= rhs; 90 | } 91 | VSOutput& operator/=( float rhs ) 92 | { 93 | pos /= rhs; 94 | n /= rhs; 95 | worldPos /= rhs; 96 | return *this; 97 | } 98 | VSOutput operator/( float rhs ) const 99 | { 100 | return VSOutput( *this ) /= rhs; 101 | } 102 | public: 103 | Vec4 pos; 104 | Vec3 n; 105 | Vec3 worldPos; 106 | }; 107 | class VertexShader : public BaseVertexShader 108 | { 109 | public: 110 | typename BaseVertexShader::Output operator()( const Vertex& v ) const 111 | { 112 | const auto p4 = Vec4( v.pos ); 113 | return { p4 * this->worldViewProj,Vec4{ v.n,0.0f } *this->worldView,p4 * this->worldView }; 114 | } 115 | }; 116 | // default gs passes vertices through and outputs triangle 117 | typedef DefaultGeometryShader GeometryShader; 118 | // invoked for each pixel of a triangle 119 | // takes an input of attributes that are the 120 | // result of interpolating vertex attributes 121 | // and outputs a color 122 | class PixelShader : public BasePhongShader 123 | { 124 | public: 125 | template 126 | Color operator()( const Input& in ) const 127 | { 128 | return this->Shade( in,material_color ); 129 | } 130 | private: 131 | Vec3 material_color = { 0.8f,0.85f,1.0f }; 132 | }; 133 | public: 134 | VertexShader vs; 135 | GeometryShader gs; 136 | PixelShader ps; 137 | }; -------------------------------------------------------------------------------- /Engine/Vec2.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Vec2.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include "ChiliMath.h" 24 | 25 | template 26 | class _Vec2 27 | { 28 | public: 29 | _Vec2() = default; 30 | _Vec2( T x,T y ) 31 | : 32 | x( x ), 33 | y( y ) 34 | {} 35 | template 36 | explicit operator _Vec2() const 37 | { 38 | return{ (T2)x,(T2)y }; 39 | } 40 | T LenSq() const 41 | { 42 | return sq( *this ); 43 | } 44 | T Len() const 45 | { 46 | return sqrt( LenSq() ); 47 | } 48 | _Vec2& Normalize() 49 | { 50 | const T length = Len(); 51 | x /= length; 52 | y /= length; 53 | return *this; 54 | } 55 | _Vec2 GetNormalized() const 56 | { 57 | _Vec2 norm = *this; 58 | norm.Normalize(); 59 | return norm; 60 | } 61 | _Vec2 operator-() const 62 | { 63 | return _Vec2( -x,-y ); 64 | } 65 | _Vec2& operator=( const _Vec2 &rhs ) 66 | { 67 | x = rhs.x; 68 | y = rhs.y; 69 | return *this; 70 | } 71 | _Vec2& operator+=( const _Vec2 &rhs ) 72 | { 73 | x += rhs.x; 74 | y += rhs.y; 75 | return *this; 76 | } 77 | _Vec2& operator-=( const _Vec2 &rhs ) 78 | { 79 | x -= rhs.x; 80 | y -= rhs.y; 81 | return *this; 82 | } 83 | T operator*( const _Vec2 &rhs ) const 84 | { 85 | return x * rhs.x + y * rhs.y; 86 | } 87 | _Vec2 operator+( const _Vec2 &rhs ) const 88 | { 89 | return _Vec2( *this ) += rhs; 90 | } 91 | _Vec2 operator-( const _Vec2 &rhs ) const 92 | { 93 | return _Vec2( *this ) -= rhs; 94 | } 95 | _Vec2& operator*=( const T &rhs ) 96 | { 97 | x *= rhs; 98 | y *= rhs; 99 | return *this; 100 | } 101 | _Vec2 operator*( const T &rhs ) const 102 | { 103 | return _Vec2( *this ) *= rhs; 104 | } 105 | _Vec2& operator/=( const T &rhs ) 106 | { 107 | x /= rhs; 108 | y /= rhs; 109 | return *this; 110 | } 111 | _Vec2 operator/( const T &rhs ) const 112 | { 113 | return _Vec2( *this ) /= rhs; 114 | } 115 | bool operator==( const _Vec2 &rhs ) const 116 | { 117 | return x == rhs.x && y == rhs.y; 118 | } 119 | bool operator!=( const _Vec2 &rhs ) const 120 | { 121 | return !(*this == rhs); 122 | } 123 | public: 124 | T x; 125 | T y; 126 | }; 127 | 128 | typedef _Vec2 Vec2; 129 | typedef _Vec2 Ved2; 130 | typedef _Vec2 Vei2; -------------------------------------------------------------------------------- /Engine/Keyboard.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Keyboard.cpp * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #include "Keyboard.h" 22 | 23 | bool Keyboard::KeyIsPressed( unsigned char keycode ) const 24 | { 25 | return keystates[keycode]; 26 | } 27 | 28 | Keyboard::Event Keyboard::ReadKey() 29 | { 30 | if( keybuffer.size() > 0u ) 31 | { 32 | Keyboard::Event e = keybuffer.front(); 33 | keybuffer.pop(); 34 | return e; 35 | } 36 | else 37 | { 38 | return Keyboard::Event(); 39 | } 40 | } 41 | 42 | bool Keyboard::KeyIsEmpty() const 43 | { 44 | return keybuffer.empty(); 45 | } 46 | 47 | char Keyboard::ReadChar() 48 | { 49 | if( charbuffer.size() > 0u ) 50 | { 51 | unsigned char charcode = charbuffer.front(); 52 | charbuffer.pop(); 53 | return charcode; 54 | } 55 | else 56 | { 57 | return 0; 58 | } 59 | } 60 | 61 | bool Keyboard::CharIsEmpty() const 62 | { 63 | return charbuffer.empty(); 64 | } 65 | 66 | void Keyboard::FlushKey() 67 | { 68 | auto rhs = std::queue(); 69 | std::swap( keybuffer, rhs); 70 | } 71 | 72 | void Keyboard::FlushChar() 73 | { 74 | auto rhs = std::queue(); 75 | std::swap( charbuffer, rhs ); 76 | } 77 | 78 | void Keyboard::Flush() 79 | { 80 | FlushKey(); 81 | FlushChar(); 82 | } 83 | 84 | void Keyboard::EnableAutorepeat() 85 | { 86 | autorepeatEnabled = true; 87 | } 88 | 89 | void Keyboard::DisableAutorepeat() 90 | { 91 | autorepeatEnabled = false; 92 | } 93 | 94 | bool Keyboard::AutorepeatIsEnabled() const 95 | { 96 | return autorepeatEnabled; 97 | } 98 | 99 | void Keyboard::OnKeyPressed( unsigned char keycode ) 100 | { 101 | keystates[ keycode ] = true; 102 | keybuffer.push( Keyboard::Event( Keyboard::Event::Press,keycode ) ); 103 | TrimBuffer( keybuffer ); 104 | } 105 | 106 | void Keyboard::OnKeyReleased( unsigned char keycode ) 107 | { 108 | keystates[ keycode ] = false; 109 | keybuffer.push( Keyboard::Event( Keyboard::Event::Release,keycode ) ); 110 | TrimBuffer( keybuffer ); 111 | } 112 | 113 | void Keyboard::OnChar( char character ) 114 | { 115 | charbuffer.push( character ); 116 | TrimBuffer( charbuffer ); 117 | } 118 | 119 | template 120 | void Keyboard::TrimBuffer( std::queue& buffer ) 121 | { 122 | while( buffer.size() > bufferSize ) 123 | { 124 | buffer.pop(); 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /Engine/Plane.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "Vec2.h" 6 | #include "Vec3.h" 7 | #include "IndexedTriangleList.h" 8 | 9 | class Plane 10 | { 11 | public: 12 | template 13 | static IndexedTriangleList GetPlain( int divisions_x = 7,int divisions_y = 7,float width = 1.0f,float height = 1.0f ) 14 | { 15 | const int nVertices_x = divisions_x + 1; 16 | const int nVertices_y = divisions_y + 1; 17 | std::vector vertices( nVertices_x * nVertices_y ); 18 | // give V a ctor for pos only %%%improvements 19 | { 20 | const float side_x = width / 2.0f; 21 | const float side_y = height / 2.0f; 22 | const float divisionSize_x = width / float( divisions_x ); 23 | const float divisionSize_y = height / float( divisions_y ); 24 | const Vec3 bottomLeft = { -side_x,-side_y,0.0f }; 25 | 26 | for( int y = 0,i = 0; y < nVertices_y; y++ ) 27 | { 28 | const float y_pos = float( y ) * divisionSize_y; 29 | for( int x = 0; x < nVertices_x; x++,i++ ) 30 | { 31 | vertices[i].pos = bottomLeft + Vec3{ float( x ) * divisionSize_x,y_pos,0.0f }; 32 | } 33 | } 34 | } 35 | 36 | std::vector indices; 37 | indices.reserve( sq( divisions_x * divisions_y ) * 6 ); 38 | { 39 | const auto vxy2i = [nVertices_x]( size_t x,size_t y ) 40 | { 41 | return y * nVertices_x + x; 42 | }; 43 | for( size_t y = 0; y < divisions_y; y++ ) 44 | { 45 | for( size_t x = 0; x < divisions_x; x++ ) 46 | { 47 | const std::array indexArray = 48 | { vxy2i( x,y ),vxy2i( x + 1,y ),vxy2i( x,y + 1 ),vxy2i( x + 1,y + 1 ) }; 49 | indices.push_back( indexArray[0] ); 50 | indices.push_back( indexArray[2] ); 51 | indices.push_back( indexArray[1] ); 52 | indices.push_back( indexArray[1] ); 53 | indices.push_back( indexArray[2] ); 54 | indices.push_back( indexArray[3] ); 55 | } 56 | } 57 | } 58 | 59 | return{ std::move( vertices ),std::move( indices ) }; 60 | } 61 | template 62 | static IndexedTriangleList GetSkinned( int divisions_x = 7,int divisions_y = 7,float width = 1.0f,float height = 1.0f,float tScale = 1.0f ) 63 | { 64 | auto itlist = GetPlain( divisions_x,divisions_y,width,height ); 65 | { 66 | const int nVertices_x = divisions_x + 1; 67 | const int nVertices_y = divisions_y + 1; 68 | const float tDivisionSize_x = width / float( divisions_x ); 69 | const float tDivisionSize_y = height / float( divisions_y ); 70 | const Vec2 tBottomLeft = { 0.0f,1.0f }; 71 | 72 | for( int y = 0,i = 0; y < nVertices_y; y++ ) 73 | { 74 | const float y_t = (-float( y ) * tDivisionSize_y) / tScale; 75 | for( int x = 0; x < nVertices_x; x++,i++ ) 76 | { 77 | itlist.vertices[i].t = tBottomLeft + Vec2{ (float( x ) * tDivisionSize_x) / tScale,y_t }; 78 | } 79 | } 80 | } 81 | 82 | return itlist; 83 | } 84 | template 85 | static IndexedTriangleList GetNormals( int divisions_x = 7,int divisions_y = 7,float width = 1.0f,float height = 1.0f ) 86 | { 87 | auto itlist = GetPlain( divisions_x,divisions_y,width,height ); 88 | for( auto& v : itlist.vertices ) 89 | { 90 | v.n = { 0.0f,0.0f,-1.0f }; 91 | } 92 | 93 | return itlist; 94 | } 95 | template 96 | static IndexedTriangleList GetSkinnedNormals( int divisions_x = 7,int divisions_y = 7,float width = 1.0f,float height = 1.0f,float tScale = 1.0f ) 97 | { 98 | auto itlist = GetSkinned( divisions_x,divisions_y,width,height,tScale ); 99 | for( auto& v : itlist.vertices ) 100 | { 101 | v.n = { 0.0f,0.0f,-1.0f }; 102 | } 103 | 104 | return itlist; 105 | } 106 | }; -------------------------------------------------------------------------------- /Engine/SolidEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "BaseVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | 7 | // solid color attribute not interpolated 8 | class SolidEffect 9 | { 10 | public: 11 | // the vertex type that will be input into the pipeline 12 | class Vertex 13 | { 14 | public: 15 | Vertex() = default; 16 | Vertex( const Vec3& pos ) 17 | : 18 | pos( pos ) 19 | {} 20 | Vertex( const Vec3& pos,const Vertex& src ) 21 | : 22 | color( src.color ), 23 | pos( pos ) 24 | {} 25 | Vertex( const Vec3& pos,const Color& color ) 26 | : 27 | color( color ), 28 | pos( pos ) 29 | {} 30 | Vertex& operator+=( const Vertex& rhs ) 31 | { 32 | pos += rhs.pos; 33 | return *this; 34 | } 35 | Vertex operator+( const Vertex& rhs ) const 36 | { 37 | return Vertex( *this ) += rhs; 38 | } 39 | Vertex& operator-=( const Vertex& rhs ) 40 | { 41 | pos -= rhs.pos; 42 | return *this; 43 | } 44 | Vertex operator-( const Vertex& rhs ) const 45 | { 46 | return Vertex( *this ) -= rhs; 47 | } 48 | Vertex& operator*=( float rhs ) 49 | { 50 | pos *= rhs; 51 | return *this; 52 | } 53 | Vertex operator*( float rhs ) const 54 | { 55 | return Vertex( *this ) *= rhs; 56 | } 57 | Vertex& operator/=( float rhs ) 58 | { 59 | pos /= rhs; 60 | return *this; 61 | } 62 | Vertex operator/( float rhs ) const 63 | { 64 | return Vertex( *this ) /= rhs; 65 | } 66 | public: 67 | Vec3 pos; 68 | Color color; 69 | }; 70 | // vertex type solid effect 71 | // only pos is interpolated 72 | class VSOutput 73 | { 74 | public: 75 | VSOutput() = default; 76 | VSOutput( const Vec4& pos ) 77 | : 78 | pos( pos ) 79 | {} 80 | VSOutput( const Vec4& pos,const Vertex& src ) 81 | : 82 | color( src.color ), 83 | pos( pos ) 84 | {} 85 | VSOutput( const Vec4& pos,const Color& color ) 86 | : 87 | color( color ), 88 | pos( pos ) 89 | {} 90 | VSOutput& operator+=( const VSOutput& rhs ) 91 | { 92 | pos += rhs.pos; 93 | return *this; 94 | } 95 | VSOutput operator+( const VSOutput& rhs ) const 96 | { 97 | return VSOutput( *this ) += rhs; 98 | } 99 | VSOutput& operator-=( const VSOutput& rhs ) 100 | { 101 | pos -= rhs.pos; 102 | return *this; 103 | } 104 | VSOutput operator-( const VSOutput& rhs ) const 105 | { 106 | return VSOutput( *this ) -= rhs; 107 | } 108 | VSOutput& operator*=( float rhs ) 109 | { 110 | pos *= rhs; 111 | return *this; 112 | } 113 | VSOutput operator*( float rhs ) const 114 | { 115 | return VSOutput( *this ) *= rhs; 116 | } 117 | VSOutput& operator/=( float rhs ) 118 | { 119 | pos /= rhs; 120 | return *this; 121 | } 122 | VSOutput operator/( float rhs ) const 123 | { 124 | return VSOutput( *this ) /= rhs; 125 | } 126 | public: 127 | Vec4 pos; 128 | Color color; 129 | }; 130 | class VertexShader : public BaseVertexShader 131 | { 132 | public: 133 | Output operator()( const Vertex& v ) const 134 | { 135 | return{ Vec4( v.pos ) * worldViewProj,v.color }; 136 | } 137 | }; 138 | // default gs passes vertices through and outputs triangle 139 | typedef DefaultGeometryShader GeometryShader; 140 | // invoked for each pixel of a triangle 141 | // takes an input of attributes that are the 142 | // result of interpolating vertex attributes 143 | // and outputs a color 144 | class PixelShader 145 | { 146 | public: 147 | template 148 | Color operator()( const I& in ) const 149 | { 150 | return in.color; 151 | } 152 | }; 153 | public: 154 | VertexShader vs; 155 | GeometryShader gs; 156 | PixelShader ps; 157 | }; -------------------------------------------------------------------------------- /Engine/Game.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Game.cpp * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #include "MainWindow.h" 22 | #include "Game.h" 23 | #include "Sphere.h" 24 | #include "TestTriangle.h" 25 | //#include "CubeSkinScene.h" 26 | //#include "CubeVertexColorScene.h" 27 | //#include "CubeSolidScene.h" 28 | //#include "DoubleCubeScene.h" 29 | //#include "VertexWaveScene.h" 30 | //#include "CubeVertexPositionColorScene.h" 31 | //#include "CubeSolidGeometryScene.h" 32 | //#include "CubeFlatIndependentScene.h" 33 | //#include "GeometryFlatScene.h" 34 | //#include "GouraudScene.h" 35 | //#include "GouraudPointScene.h" 36 | //#include "PhongPointScene.h" 37 | #include "SpecularPhongPointScene.h" 38 | #include 39 | 40 | Game::Game( MainWindow& wnd ) 41 | : 42 | wnd( wnd ), 43 | gfx( wnd ) 44 | { 45 | scenes.push_back( std::make_unique( gfx ) ); 46 | curScene = scenes.begin(); 47 | OutputSceneName(); 48 | } 49 | 50 | void Game::Go() 51 | { 52 | gfx.BeginFrame(); 53 | UpdateModel(); 54 | ComposeFrame(); 55 | gfx.EndFrame(); 56 | } 57 | 58 | void Game::UpdateModel() 59 | { 60 | const float dt = ft.Mark(); 61 | // cycle through scenes when tab is pressed 62 | while( !wnd.kbd.KeyIsEmpty() ) 63 | { 64 | const auto e = wnd.kbd.ReadKey(); 65 | if( e.GetCode() == VK_TAB && e.IsPress() ) 66 | { 67 | if( wnd.kbd.KeyIsPressed( VK_SHIFT ) ) 68 | { 69 | ReverseCycleScenes(); 70 | } 71 | else 72 | { 73 | CycleScenes(); 74 | } 75 | } 76 | else if( e.GetCode() == VK_ESCAPE && e.IsPress() ) 77 | { 78 | wnd.Kill(); 79 | } 80 | } 81 | // update scene 82 | (*curScene)->Update( wnd.kbd,wnd.mouse,dt ); 83 | } 84 | 85 | void Game::CycleScenes() 86 | { 87 | if( ++curScene == scenes.end() ) 88 | { 89 | curScene = scenes.begin(); 90 | } 91 | OutputSceneName(); 92 | } 93 | 94 | void Game::ReverseCycleScenes() 95 | { 96 | if( curScene == scenes.begin() ) 97 | { 98 | curScene = scenes.end() - 1; 99 | } 100 | else 101 | { 102 | --curScene; 103 | } 104 | OutputSceneName(); 105 | } 106 | 107 | void Game::OutputSceneName() const 108 | { 109 | std::stringstream ss; 110 | const std::string stars( (*curScene)->GetName().size() + 4,'*' ); 111 | 112 | ss << stars << std::endl 113 | << "* " << (*curScene)->GetName() << " *" << std::endl 114 | << stars << std::endl; 115 | OutputDebugStringA( ss.str().c_str() ); 116 | } 117 | 118 | void Game::ComposeFrame() 119 | { 120 | // draw scene 121 | (*curScene)->Draw(); 122 | } -------------------------------------------------------------------------------- /Engine/Mouse.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Mouse.cpp * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #include "Mouse.h" 22 | #include "Vec2.h" 23 | 24 | 25 | Vei2 Mouse::GetPos() const 26 | { 27 | return { x,y }; 28 | } 29 | 30 | int Mouse::GetPosX() const 31 | { 32 | return x; 33 | } 34 | 35 | int Mouse::GetPosY() const 36 | { 37 | return y; 38 | } 39 | 40 | bool Mouse::LeftIsPressed() const 41 | { 42 | return leftIsPressed; 43 | } 44 | 45 | bool Mouse::RightIsPressed() const 46 | { 47 | return rightIsPressed; 48 | } 49 | 50 | bool Mouse::IsInWindow() const 51 | { 52 | return isInWindow; 53 | } 54 | 55 | Mouse::Event Mouse::Read() 56 | { 57 | if( buffer.size() > 0u ) 58 | { 59 | Mouse::Event e = buffer.front(); 60 | buffer.pop(); 61 | return e; 62 | } 63 | else 64 | { 65 | return Mouse::Event(); 66 | } 67 | } 68 | 69 | void Mouse::Flush() 70 | { 71 | auto rhs = std::queue(); 72 | std::swap( buffer, rhs ); 73 | } 74 | 75 | void Mouse::OnMouseLeave() 76 | { 77 | isInWindow = false; 78 | } 79 | 80 | void Mouse::OnMouseEnter() 81 | { 82 | isInWindow = true; 83 | } 84 | 85 | void Mouse::OnMouseMove( int newx,int newy ) 86 | { 87 | x = newx; 88 | y = newy; 89 | 90 | buffer.push( Mouse::Event( Mouse::Event::Move,*this ) ); 91 | TrimBuffer(); 92 | } 93 | 94 | void Mouse::OnLeftPressed( int x,int y ) 95 | { 96 | leftIsPressed = true; 97 | 98 | buffer.push( Mouse::Event( Mouse::Event::LPress,*this ) ); 99 | TrimBuffer(); 100 | } 101 | 102 | void Mouse::OnLeftReleased( int x,int y ) 103 | { 104 | leftIsPressed = false; 105 | 106 | buffer.push( Mouse::Event( Mouse::Event::LRelease,*this ) ); 107 | TrimBuffer(); 108 | } 109 | 110 | void Mouse::OnRightPressed( int x,int y ) 111 | { 112 | rightIsPressed = true; 113 | 114 | buffer.push( Mouse::Event( Mouse::Event::RPress,*this ) ); 115 | TrimBuffer(); 116 | } 117 | 118 | void Mouse::OnRightReleased( int x,int y ) 119 | { 120 | rightIsPressed = false; 121 | 122 | buffer.push( Mouse::Event( Mouse::Event::RRelease,*this ) ); 123 | TrimBuffer(); 124 | } 125 | 126 | void Mouse::OnWheelUp( int x,int y ) 127 | { 128 | buffer.push( Mouse::Event( Mouse::Event::WheelUp,*this ) ); 129 | TrimBuffer(); 130 | } 131 | 132 | void Mouse::OnWheelDown( int x,int y ) 133 | { 134 | buffer.push( Mouse::Event( Mouse::Event::WheelDown,*this ) ); 135 | TrimBuffer(); 136 | } 137 | 138 | void Mouse::TrimBuffer() 139 | { 140 | while( buffer.size() > bufferSize ) 141 | { 142 | buffer.pop(); 143 | } 144 | } -------------------------------------------------------------------------------- /Engine/Mouse.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Mouse.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include 23 | #include "Vec2.h" 24 | 25 | class Mouse 26 | { 27 | friend class MainWindow; 28 | public: 29 | class Event 30 | { 31 | public: 32 | enum Type 33 | { 34 | LPress, 35 | LRelease, 36 | RPress, 37 | RRelease, 38 | WheelUp, 39 | WheelDown, 40 | Move, 41 | Invalid 42 | }; 43 | private: 44 | Type type; 45 | bool leftIsPressed; 46 | bool rightIsPressed; 47 | int x; 48 | int y; 49 | public: 50 | Event() 51 | : 52 | type( Invalid ), 53 | leftIsPressed( false ), 54 | rightIsPressed( false ), 55 | x( 0 ), 56 | y( 0 ) 57 | {} 58 | Event( Type type,const Mouse& parent ) 59 | : 60 | type( type ), 61 | leftIsPressed( parent.leftIsPressed ), 62 | rightIsPressed( parent.rightIsPressed ), 63 | x( parent.x ), 64 | y( parent.y ) 65 | {} 66 | bool IsValid() const 67 | { 68 | return type != Invalid; 69 | } 70 | Type GetType() const 71 | { 72 | return type; 73 | } 74 | Vei2 GetPos() const 75 | { 76 | return { x,y }; 77 | } 78 | int GetPosX() const 79 | { 80 | return x; 81 | } 82 | int GetPosY() const 83 | { 84 | return y; 85 | } 86 | bool LeftIsPressed() const 87 | { 88 | return leftIsPressed; 89 | } 90 | bool RightIsPressed() const 91 | { 92 | return rightIsPressed; 93 | } 94 | }; 95 | public: 96 | Mouse() = default; 97 | Mouse( const Mouse& ) = delete; 98 | Mouse& operator=( const Mouse& ) = delete; 99 | Vei2 GetPos() const; 100 | int GetPosX() const; 101 | int GetPosY() const; 102 | bool LeftIsPressed() const; 103 | bool RightIsPressed() const; 104 | bool IsInWindow() const; 105 | Mouse::Event Read(); 106 | bool IsEmpty() const 107 | { 108 | return buffer.empty(); 109 | } 110 | void Flush(); 111 | private: 112 | void OnMouseMove( int x,int y ); 113 | void OnMouseLeave(); 114 | void OnMouseEnter(); 115 | void OnLeftPressed( int x,int y ); 116 | void OnLeftReleased( int x,int y ); 117 | void OnRightPressed( int x,int y ); 118 | void OnRightReleased( int x,int y ); 119 | void OnWheelUp( int x,int y ); 120 | void OnWheelDown( int x,int y ); 121 | void TrimBuffer(); 122 | private: 123 | static constexpr unsigned int bufferSize = 4u; 124 | int x = 0; 125 | int y = 0; 126 | bool leftIsPressed = false; 127 | bool rightIsPressed = false; 128 | bool isInWindow = false; 129 | std::queue buffer; 130 | }; -------------------------------------------------------------------------------- /Engine/GouraudPointScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "GouraudPointEffect.h" 8 | #include "SolidEffect.h" 9 | 10 | class GouraudPointScene : public Scene 11 | { 12 | public: 13 | typedef ::Pipeline Pipeline; 14 | typedef ::Pipeline LightIndicatorPipeline; 15 | typedef Pipeline::Vertex Vertex; 16 | public: 17 | GouraudPointScene( Graphics& gfx,IndexedTriangleList tl ) 18 | : 19 | itlist( std::move( tl ) ), 20 | pZb( std::make_shared( gfx.ScreenWidth,gfx.ScreenHeight ) ), 21 | pipeline( gfx,pZb ), 22 | liPipeline( gfx,pZb ), 23 | Scene( "gouraud point shader scene free mesh" ) 24 | { 25 | itlist.AdjustToTrueCenter(); 26 | offset_z = itlist.GetRadius() * 1.6f; 27 | for( auto& v : lightIndicator.vertices ) 28 | { 29 | v.color = Colors::White; 30 | } 31 | } 32 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 33 | { 34 | if( kbd.KeyIsPressed( 'Q' ) ) 35 | { 36 | theta_x = wrap_angle( theta_x + dTheta * dt ); 37 | } 38 | if( kbd.KeyIsPressed( 'W' ) ) 39 | { 40 | theta_y = wrap_angle( theta_y + dTheta * dt ); 41 | } 42 | if( kbd.KeyIsPressed( 'E' ) ) 43 | { 44 | theta_z = wrap_angle( theta_z + dTheta * dt ); 45 | } 46 | if( kbd.KeyIsPressed( 'A' ) ) 47 | { 48 | theta_x = wrap_angle( theta_x - dTheta * dt ); 49 | } 50 | if( kbd.KeyIsPressed( 'S' ) ) 51 | { 52 | theta_y = wrap_angle( theta_y - dTheta * dt ); 53 | } 54 | if( kbd.KeyIsPressed( 'D' ) ) 55 | { 56 | theta_z = wrap_angle( theta_z - dTheta * dt ); 57 | } 58 | if( kbd.KeyIsPressed( 'U' ) ) 59 | { 60 | lpos_x += 0.2f * dt; 61 | } 62 | if( kbd.KeyIsPressed( 'I' ) ) 63 | { 64 | lpos_y += 0.2f * dt; 65 | } 66 | if( kbd.KeyIsPressed( 'O' ) ) 67 | { 68 | lpos_z += 0.2f * dt; 69 | } 70 | if( kbd.KeyIsPressed( 'J' ) ) 71 | { 72 | lpos_x -= 0.2f * dt; 73 | } 74 | if( kbd.KeyIsPressed( 'K' ) ) 75 | { 76 | lpos_y -= 0.2f * dt; 77 | } 78 | if( kbd.KeyIsPressed( 'L' ) ) 79 | { 80 | lpos_z -= 0.2f * dt; 81 | } 82 | if( kbd.KeyIsPressed( 'R' ) ) 83 | { 84 | offset_z += 0.2f * dt; 85 | } 86 | if( kbd.KeyIsPressed( 'F' ) ) 87 | { 88 | offset_z -= 0.2f * dt; 89 | } 90 | } 91 | virtual void Draw() override 92 | { 93 | pipeline.BeginFrame(); 94 | // generate rotation matrix from euler angles 95 | // translation from offset 96 | const Mat3 rot = 97 | Mat3::RotationX( theta_x ) * 98 | Mat3::RotationY( theta_y ) * 99 | Mat3::RotationZ( theta_z ); 100 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 101 | // set pipeline transform 102 | pipeline.effect.vs.BindRotation( rot ); 103 | pipeline.effect.vs.BindTranslation( trans ); 104 | pipeline.effect.vs.SetLightPosition( { lpos_x,lpos_y,lpos_z } ); 105 | // render triangles 106 | pipeline.Draw( itlist ); 107 | 108 | // draw light indicator with different pipeline 109 | // don't call beginframe on this pipeline b/c wanna keep zbuffer contents 110 | // (don't like this assymetry but we'll live with it for now) 111 | liPipeline.effect.vs.BindTranslation( { lpos_x,lpos_y,lpos_z } ); 112 | liPipeline.effect.vs.BindRotation( Mat3::Identity() ); 113 | liPipeline.Draw( lightIndicator ); 114 | } 115 | private: 116 | IndexedTriangleList itlist; 117 | IndexedTriangleList lightIndicator = Sphere::GetPlain( 0.05f ); 118 | std::shared_ptr pZb; 119 | Pipeline pipeline; 120 | LightIndicatorPipeline liPipeline; 121 | static constexpr float dTheta = PI; 122 | float offset_z = 2.0f; 123 | float theta_x = 0.0f; 124 | float theta_y = 0.0f; 125 | float theta_z = 0.0f; 126 | float lpos_x = 0.0f; 127 | float lpos_y = 0.0f; 128 | float lpos_z = 0.6f; 129 | }; -------------------------------------------------------------------------------- /Engine/PhongPointScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "Cube.h" 5 | #include "Mat.h" 6 | #include "Pipeline.h" 7 | #include "PhongPointEffect.h" 8 | #include "SolidEffect.h" 9 | #include "Sphere.h" 10 | 11 | class PhongPointScene : public Scene 12 | { 13 | public: 14 | typedef ::Pipeline Pipeline; 15 | typedef ::Pipeline LightIndicatorPipeline; 16 | typedef Pipeline::Vertex Vertex; 17 | public: 18 | PhongPointScene( Graphics& gfx,IndexedTriangleList tl ) 19 | : 20 | itlist( std::move( tl ) ), 21 | pZb( std::make_shared( gfx.ScreenWidth,gfx.ScreenHeight ) ), 22 | pipeline( gfx,pZb ), 23 | liPipeline( gfx,pZb ), 24 | Scene( "phong point shader scene free mesh" ) 25 | { 26 | itlist.AdjustToTrueCenter(); 27 | offset_z = itlist.GetRadius() * 1.6f; 28 | for( auto& v : lightIndicator.vertices ) 29 | { 30 | v.color = Colors::White; 31 | } 32 | } 33 | virtual void Update( Keyboard& kbd,Mouse& mouse,float dt ) override 34 | { 35 | if( kbd.KeyIsPressed( 'Q' ) ) 36 | { 37 | theta_x = wrap_angle( theta_x + dTheta * dt ); 38 | } 39 | if( kbd.KeyIsPressed( 'W' ) ) 40 | { 41 | theta_y = wrap_angle( theta_y + dTheta * dt ); 42 | } 43 | if( kbd.KeyIsPressed( 'E' ) ) 44 | { 45 | theta_z = wrap_angle( theta_z + dTheta * dt ); 46 | } 47 | if( kbd.KeyIsPressed( 'A' ) ) 48 | { 49 | theta_x = wrap_angle( theta_x - dTheta * dt ); 50 | } 51 | if( kbd.KeyIsPressed( 'S' ) ) 52 | { 53 | theta_y = wrap_angle( theta_y - dTheta * dt ); 54 | } 55 | if( kbd.KeyIsPressed( 'D' ) ) 56 | { 57 | theta_z = wrap_angle( theta_z - dTheta * dt ); 58 | } 59 | if( kbd.KeyIsPressed( 'U' ) ) 60 | { 61 | lpos_x += 0.2f * dt; 62 | } 63 | if( kbd.KeyIsPressed( 'I' ) ) 64 | { 65 | lpos_y += 0.2f * dt; 66 | } 67 | if( kbd.KeyIsPressed( 'O' ) ) 68 | { 69 | lpos_z += 0.2f * dt; 70 | } 71 | if( kbd.KeyIsPressed( 'J' ) ) 72 | { 73 | lpos_x -= 0.2f * dt; 74 | } 75 | if( kbd.KeyIsPressed( 'K' ) ) 76 | { 77 | lpos_y -= 0.2f * dt; 78 | } 79 | if( kbd.KeyIsPressed( 'L' ) ) 80 | { 81 | lpos_z -= 0.2f * dt; 82 | } 83 | if( kbd.KeyIsPressed( 'R' ) ) 84 | { 85 | offset_z += 0.2f * dt; 86 | } 87 | if( kbd.KeyIsPressed( 'F' ) ) 88 | { 89 | offset_z -= 0.2f * dt; 90 | } 91 | } 92 | virtual void Draw() override 93 | { 94 | pipeline.BeginFrame(); 95 | // generate rotation matrix from euler angles 96 | // translation from offset 97 | const Mat3 rot = 98 | Mat3::RotationX( theta_x ) * 99 | Mat3::RotationY( theta_y ) * 100 | Mat3::RotationZ( theta_z ); 101 | const Vec3 trans = { 0.0f,0.0f,offset_z }; 102 | // set pipeline transform 103 | pipeline.effect.vs.BindRotation( rot ); 104 | pipeline.effect.vs.BindTranslation( trans ); 105 | pipeline.effect.ps.SetLightPosition( { lpos_x,lpos_y,lpos_z } ); 106 | // render triangles 107 | pipeline.Draw( itlist ); 108 | 109 | // draw light indicator with different pipeline 110 | // don't call beginframe on this pipeline b/c wanna keep zbuffer contents 111 | // (don't like this assymetry but we'll live with it for now) 112 | liPipeline.effect.vs.BindTranslation( { lpos_x,lpos_y,lpos_z } ); 113 | liPipeline.effect.vs.BindRotation( Mat3::Identity() ); 114 | liPipeline.Draw( lightIndicator ); 115 | } 116 | private: 117 | IndexedTriangleList itlist; 118 | IndexedTriangleList lightIndicator = Sphere::GetPlain( 0.05f ); 119 | std::shared_ptr pZb; 120 | Pipeline pipeline; 121 | LightIndicatorPipeline liPipeline; 122 | static constexpr float dTheta = PI; 123 | float offset_z = 2.0f; 124 | float theta_x = 0.0f; 125 | float theta_y = 0.0f; 126 | float theta_z = 0.0f; 127 | float lpos_x = 0.0f; 128 | float lpos_y = 0.0f; 129 | float lpos_z = 0.6f; 130 | }; -------------------------------------------------------------------------------- /Engine/VertexPositionColorEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultGeometryShader.h" 5 | 6 | // color gradient effect between vertices determined by vertex position 7 | class VertexPositionColorEffect 8 | { 9 | public: 10 | // the vertex type that will be input into the pipeline 11 | class Vertex 12 | { 13 | public: 14 | Vertex() = default; 15 | Vertex( const Vec3& pos ) 16 | : 17 | pos( pos ) 18 | {} 19 | Vertex( const Vec3& pos,const Vertex& src ) 20 | : 21 | pos( pos ) 22 | {} 23 | Vertex& operator+=( const Vertex& rhs ) 24 | { 25 | pos += rhs.pos; 26 | return *this; 27 | } 28 | Vertex operator+( const Vertex& rhs ) const 29 | { 30 | return Vertex( *this ) += rhs; 31 | } 32 | Vertex& operator-=( const Vertex& rhs ) 33 | { 34 | pos -= rhs.pos; 35 | return *this; 36 | } 37 | Vertex operator-( const Vertex& rhs ) const 38 | { 39 | return Vertex( *this ) -= rhs; 40 | } 41 | Vertex& operator*=( float rhs ) 42 | { 43 | pos *= rhs; 44 | return *this; 45 | } 46 | Vertex operator*( float rhs ) const 47 | { 48 | return Vertex( *this ) *= rhs; 49 | } 50 | Vertex& operator/=( float rhs ) 51 | { 52 | pos /= rhs; 53 | return *this; 54 | } 55 | Vertex operator/( float rhs ) const 56 | { 57 | return Vertex( *this ) /= rhs; 58 | } 59 | public: 60 | Vec3 pos; 61 | }; 62 | // uses x,y,z position components to determine color 63 | class VertexShader 64 | { 65 | public: 66 | class Output 67 | { 68 | public: 69 | Output() = default; 70 | Output( const Vec3& pos ) 71 | : 72 | pos( pos ) 73 | {} 74 | Output( const Vec3& pos,const Output& src ) 75 | : 76 | color( src.color ), 77 | pos( pos ) 78 | {} 79 | Output( const Vec3& pos,const Vec3& color ) 80 | : 81 | color( color ), 82 | pos( pos ) 83 | {} 84 | Output& operator+=( const Output& rhs ) 85 | { 86 | pos += rhs.pos; 87 | color += rhs.color; 88 | return *this; 89 | } 90 | Output operator+( const Output& rhs ) const 91 | { 92 | return Output( *this ) += rhs; 93 | } 94 | Output& operator-=( const Output& rhs ) 95 | { 96 | pos -= rhs.pos; 97 | color -= rhs.color; 98 | return *this; 99 | } 100 | Output operator-( const Output& rhs ) const 101 | { 102 | return Output( *this ) -= rhs; 103 | } 104 | Output& operator*=( float rhs ) 105 | { 106 | pos *= rhs; 107 | color *= rhs; 108 | return *this; 109 | } 110 | Output operator*( float rhs ) const 111 | { 112 | return Output( *this ) *= rhs; 113 | } 114 | Output& operator/=( float rhs ) 115 | { 116 | pos /= rhs; 117 | color /= rhs; 118 | return *this; 119 | } 120 | Output operator/( float rhs ) const 121 | { 122 | return Output( *this ) /= rhs; 123 | } 124 | public: 125 | Vec3 pos; 126 | Vec3 color; 127 | }; 128 | public: 129 | void BindRotation( const Mat3& rotation_in ) 130 | { 131 | rotation = rotation_in; 132 | } 133 | void BindTranslation( const Vec3& translation_in ) 134 | { 135 | translation = translation_in; 136 | } 137 | Output operator()( const Vertex& in ) const 138 | { 139 | const auto pos = in.pos * rotation + translation; 140 | return{ pos,Vec3{ std::abs( pos.x ),std::abs( pos.y ),std::abs( pos.z ) } * 255.0f }; 141 | } 142 | private: 143 | Mat3 rotation; 144 | Vec3 translation; 145 | }; 146 | // default gs passes vertices through and outputs triangle 147 | typedef DefaultGeometryShader GeometryShader; 148 | // converts float color into packed byte color 149 | class PixelShader 150 | { 151 | public: 152 | template 153 | Color operator()( const Input& in ) const 154 | { 155 | return Color( in.color ); 156 | } 157 | }; 158 | public: 159 | VertexShader vs; 160 | GeometryShader gs; 161 | PixelShader ps; 162 | }; -------------------------------------------------------------------------------- /Engine/SolidGeometryEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultVertexShader.h" 5 | 6 | // solid color attribute taken from table in gs and not interpolated 7 | class SolidGeometryEffect 8 | { 9 | public: 10 | // the vertex type that will be input into the pipeline 11 | class Vertex 12 | { 13 | public: 14 | Vertex() = default; 15 | Vertex( const Vec3& pos ) 16 | : 17 | pos( pos ) 18 | {} 19 | Vertex( const Vec3& pos,const Vertex& src ) 20 | : 21 | pos( pos ) 22 | {} 23 | Vertex& operator+=( const Vertex& rhs ) 24 | { 25 | pos += rhs.pos; 26 | return *this; 27 | } 28 | Vertex operator+( const Vertex& rhs ) const 29 | { 30 | return Vertex( *this ) += rhs; 31 | } 32 | Vertex& operator-=( const Vertex& rhs ) 33 | { 34 | pos -= rhs.pos; 35 | return *this; 36 | } 37 | Vertex operator-( const Vertex& rhs ) const 38 | { 39 | return Vertex( *this ) -= rhs; 40 | } 41 | Vertex& operator*=( float rhs ) 42 | { 43 | pos *= rhs; 44 | return *this; 45 | } 46 | Vertex operator*( float rhs ) const 47 | { 48 | return Vertex( *this ) *= rhs; 49 | } 50 | Vertex& operator/=( float rhs ) 51 | { 52 | pos /= rhs; 53 | return *this; 54 | } 55 | Vertex operator/( float rhs ) const 56 | { 57 | return Vertex( *this ) /= rhs; 58 | } 59 | public: 60 | Vec3 pos; 61 | }; 62 | // default vs rotates and translates vertices 63 | // does not touch attributes 64 | typedef DefaultVertexShader VertexShader; 65 | // gs colors vertices using their index from a table 66 | // every two triangles are colored from the same entry 67 | class GeometryShader 68 | { 69 | public: 70 | class Output 71 | { 72 | public: 73 | Output() = default; 74 | Output( const Vec3& pos ) 75 | : 76 | pos( pos ) 77 | {} 78 | Output( const Vec3& pos,const Output& src ) 79 | : 80 | color( src.color ), 81 | pos( pos ) 82 | {} 83 | Output( const Vec3& pos,const Color& color ) 84 | : 85 | color( color ), 86 | pos( pos ) 87 | {} 88 | Output& operator+=( const Output& rhs ) 89 | { 90 | pos += rhs.pos; 91 | return *this; 92 | } 93 | Output operator+( const Output& rhs ) const 94 | { 95 | return Output( *this ) += rhs; 96 | } 97 | Output& operator-=( const Output& rhs ) 98 | { 99 | pos -= rhs.pos; 100 | return *this; 101 | } 102 | Output operator-( const Output& rhs ) const 103 | { 104 | return Output( *this ) -= rhs; 105 | } 106 | Output& operator*=( float rhs ) 107 | { 108 | pos *= rhs; 109 | return *this; 110 | } 111 | Output operator*( float rhs ) const 112 | { 113 | return Output( *this ) *= rhs; 114 | } 115 | Output& operator/=( float rhs ) 116 | { 117 | pos /= rhs; 118 | return *this; 119 | } 120 | Output operator/( float rhs ) const 121 | { 122 | return Output( *this ) /= rhs; 123 | } 124 | public: 125 | Vec3 pos; 126 | Color color; 127 | }; 128 | public: 129 | Triangle operator()( const VertexShader::Output& in0,const VertexShader::Output& in1,const VertexShader::Output& in2,size_t triangle_index ) const 130 | { 131 | return{ 132 | { in0.pos,triangle_colors[triangle_index/2] }, 133 | { in1.pos,triangle_colors[triangle_index/2] }, 134 | { in2.pos,triangle_colors[triangle_index/2] } 135 | }; 136 | }; 137 | void BindColors( std::vector colors ) 138 | { 139 | triangle_colors = std::move( colors ); 140 | } 141 | private: 142 | std::vector triangle_colors; 143 | }; 144 | // invoked for each pixel of a triangle 145 | // takes an input of attributes that are the 146 | // result of interpolating vertex attributes 147 | // and outputs a color 148 | class PixelShader 149 | { 150 | public: 151 | template 152 | Color operator()( const Input& in ) const 153 | { 154 | return in.color; 155 | } 156 | }; 157 | public: 158 | VertexShader vs; 159 | GeometryShader gs; 160 | PixelShader ps; 161 | }; -------------------------------------------------------------------------------- /Engine/Colors.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Colors.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include "Vec3.h" 24 | 25 | class Color 26 | { 27 | public: 28 | unsigned int dword; 29 | public: 30 | constexpr Color() : dword() {} 31 | constexpr Color( const Color& col ) 32 | : 33 | dword( col.dword ) 34 | {} 35 | constexpr Color( unsigned int dw ) 36 | : 37 | dword( dw ) 38 | {} 39 | constexpr Color( unsigned char x,unsigned char r,unsigned char g,unsigned char b ) 40 | : 41 | dword( (x << 24u) | (r << 16u) | (g << 8u) | b ) 42 | {} 43 | constexpr Color( unsigned char r,unsigned char g,unsigned char b ) 44 | : 45 | dword( (r << 16u) | (g << 8u) | b ) 46 | {} 47 | constexpr Color( Color col,unsigned char x ) 48 | : 49 | Color( (x << 24u) | col.dword ) 50 | {} 51 | explicit Color( const Vec3& cf ) 52 | : 53 | Color( unsigned char( cf.x ),unsigned char( cf.y ),unsigned char( cf.z ) ) 54 | {} 55 | explicit operator Vec3() const 56 | { 57 | return{ float( GetR() ),float( GetG() ), float( GetB() ) }; 58 | } 59 | Color& operator =( Color color ) 60 | { 61 | dword = color.dword; 62 | return *this; 63 | } 64 | constexpr unsigned char GetX() const 65 | { 66 | return dword >> 24u; 67 | } 68 | constexpr unsigned char GetA() const 69 | { 70 | return GetX(); 71 | } 72 | constexpr unsigned char GetR() const 73 | { 74 | return (dword >> 16u) & 0xFFu; 75 | } 76 | constexpr unsigned char GetG() const 77 | { 78 | return (dword >> 8u) & 0xFFu; 79 | } 80 | constexpr unsigned char GetB() const 81 | { 82 | return dword & 0xFFu; 83 | } 84 | void SetX( unsigned char x ) 85 | { 86 | dword = (dword & 0xFFFFFFu) | (x << 24u); 87 | } 88 | void SetA( unsigned char a ) 89 | { 90 | SetX( a ); 91 | } 92 | void SetR( unsigned char r ) 93 | { 94 | dword = (dword & 0xFF00FFFFu) | (r << 16u); 95 | } 96 | void SetG( unsigned char g ) 97 | { 98 | dword = (dword & 0xFFFF00FFu) | (g << 8u); 99 | } 100 | void SetB( unsigned char b ) 101 | { 102 | dword = (dword & 0xFFFFFF00u) | b; 103 | } 104 | }; 105 | 106 | namespace Colors 107 | { 108 | static constexpr Color MakeRGB( unsigned char r,unsigned char g,unsigned char b ) 109 | { 110 | return (r << 16) | (g << 8) | b; 111 | } 112 | static constexpr Color White = MakeRGB( 255u,255u,255u ); 113 | static constexpr Color Black = MakeRGB( 0u,0u,0u ); 114 | static constexpr Color Gray = MakeRGB( 0x80u,0x80u,0x80u ); 115 | static constexpr Color LightGray = MakeRGB( 0xD3u,0xD3u,0xD3u ); 116 | static constexpr Color Red = MakeRGB( 255u,0u,0u ); 117 | static constexpr Color Green = MakeRGB( 0u,255u,0u ); 118 | static constexpr Color Blue = MakeRGB( 0u,0u,255u ); 119 | static constexpr Color Yellow = MakeRGB( 255u,255u,0u ); 120 | static constexpr Color Cyan = MakeRGB( 0u,255u,255u ); 121 | static constexpr Color Magenta = MakeRGB( 255u,0u,255u ); 122 | } -------------------------------------------------------------------------------- /Engine/PhongPointEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultGeometryShader.h" 5 | 6 | // flat shading with vertex normals 7 | class PhongPointEffect 8 | { 9 | public: 10 | // the vertex type that will be input into the pipeline 11 | class Vertex 12 | { 13 | public: 14 | Vertex() = default; 15 | Vertex( const Vec3& pos ) 16 | : 17 | pos( pos ) 18 | {} 19 | Vertex( const Vec3& pos,const Vertex& src ) 20 | : 21 | n( src.n ), 22 | pos( pos ) 23 | {} 24 | Vertex( const Vec3& pos,const Vec3& n ) 25 | : 26 | n( n ), 27 | pos( pos ) 28 | {} 29 | public: 30 | Vec3 pos; 31 | Vec3 n; 32 | }; 33 | // calculate color based on normal to light angle 34 | // no interpolation of color attribute 35 | class VertexShader 36 | { 37 | public: 38 | class Output 39 | { 40 | public: 41 | Output() = default; 42 | Output( const Vec3& pos ) 43 | : 44 | pos( pos ) 45 | {} 46 | Output( const Vec3& pos,const Output& src ) 47 | : 48 | n( src.n ), 49 | worldPos( src.worldPos ), 50 | pos( pos ) 51 | {} 52 | Output( const Vec3& pos,const Vec3& n,const Vec3& worldPos ) 53 | : 54 | n( n ), 55 | pos( pos ), 56 | worldPos( worldPos ) 57 | {} 58 | Output& operator+=( const Output& rhs ) 59 | { 60 | pos += rhs.pos; 61 | n += rhs.n; 62 | worldPos += rhs.worldPos; 63 | return *this; 64 | } 65 | Output operator+( const Output& rhs ) const 66 | { 67 | return Output( *this ) += rhs; 68 | } 69 | Output& operator-=( const Output& rhs ) 70 | { 71 | pos -= rhs.pos; 72 | n -= rhs.n; 73 | worldPos -= rhs.worldPos; 74 | return *this; 75 | } 76 | Output operator-( const Output& rhs ) const 77 | { 78 | return Output( *this ) -= rhs; 79 | } 80 | Output& operator*=( float rhs ) 81 | { 82 | pos *= rhs; 83 | n *= rhs; 84 | worldPos *= rhs; 85 | return *this; 86 | } 87 | Output operator*( float rhs ) const 88 | { 89 | return Output( *this ) *= rhs; 90 | } 91 | Output& operator/=( float rhs ) 92 | { 93 | pos /= rhs; 94 | n /= rhs; 95 | worldPos /= rhs; 96 | return *this; 97 | } 98 | Output operator/( float rhs ) const 99 | { 100 | return Output( *this ) /= rhs; 101 | } 102 | public: 103 | Vec3 pos; 104 | Vec3 n; 105 | Vec3 worldPos; 106 | }; 107 | public: 108 | void BindRotation( const Mat3& rotation_in ) 109 | { 110 | rotation = rotation_in; 111 | } 112 | void BindTranslation( const Vec3& translation_in ) 113 | { 114 | translation = translation_in; 115 | } 116 | Output operator()( const Vertex& v ) const 117 | { 118 | const auto pos = v.pos * rotation + translation; 119 | return{ pos,v.n * rotation,pos }; 120 | } 121 | private: 122 | Mat3 rotation; 123 | Vec3 translation; 124 | }; 125 | // default gs passes vertices through and outputs triangle 126 | typedef DefaultGeometryShader GeometryShader; 127 | // invoked for each pixel of a triangle 128 | // takes an input of attributes that are the 129 | // result of interpolating vertex attributes 130 | // and outputs a color 131 | class PixelShader 132 | { 133 | public: 134 | template 135 | Color operator()( const Input& in ) const 136 | { 137 | // vertex to light data 138 | const auto v_to_l = light_pos - in.worldPos; 139 | const auto dist = v_to_l.Len(); 140 | const auto dir = v_to_l / dist; 141 | // calculate attenuation 142 | const auto attenuation = 1.0f / 143 | (constant_attenuation + linear_attenuation * dist + quadradic_attenuation * sq( dist )); 144 | // calculate intensity based on angle of incidence and attenuation 145 | const auto d = light_diffuse * attenuation * std::max( 0.0f,in.n.GetNormalized() * dir ); 146 | // add diffuse+ambient, filter by material color, saturate and scale 147 | return Color( material_color.GetHadamard( d + light_ambient ).Saturate() * 255.0f ); 148 | } 149 | void SetDiffuseLight( const Vec3& c ) 150 | { 151 | light_diffuse = c; 152 | } 153 | void SetAmbientLight( const Vec3& c ) 154 | { 155 | light_ambient = c; 156 | } 157 | void SetLightPosition( const Vec3& pos_in ) 158 | { 159 | light_pos = pos_in; 160 | } 161 | private: 162 | Vec3 light_pos = { 0.0f,0.0f,0.5f }; 163 | Vec3 light_diffuse = { 1.0f,1.0f,1.0f }; 164 | Vec3 light_ambient = { 0.1f,0.1f,0.1f }; 165 | Vec3 material_color = { 0.8f,0.85f,1.0f }; 166 | float linear_attenuation = 1.0f; 167 | float quadradic_attenuation = 2.619f; 168 | float constant_attenuation = 0.382f; 169 | }; 170 | public: 171 | VertexShader vs; 172 | GeometryShader gs; 173 | PixelShader ps; 174 | }; -------------------------------------------------------------------------------- /Engine/Vec3.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Vec2.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include 24 | #include "ChiliMath.h" 25 | #include "Vec2.h" 26 | 27 | template 28 | class _Vec3 : public _Vec2 29 | { 30 | public: 31 | _Vec3() = default; 32 | _Vec3( T x,T y,T z ) 33 | : 34 | _Vec2( x, y ), 35 | z( z ) 36 | {} 37 | template 38 | explicit operator _Vec3() const 39 | { 40 | return{ (T2)this->x,(T2)this->y,(T2)z }; 41 | } 42 | T LenSq() const 43 | { 44 | return sq( *this ); 45 | } 46 | T Len() const 47 | { 48 | return static_cast(sqrt( LenSq() )); 49 | } 50 | _Vec3& Normalize() 51 | { 52 | const T length = Len(); 53 | this->x /= length; 54 | this->y /= length; 55 | z /= length; 56 | return *this; 57 | } 58 | _Vec3 GetNormalized() const 59 | { 60 | _Vec3 norm = *this; 61 | norm.Normalize(); 62 | return norm; 63 | } 64 | _Vec3 operator-() const 65 | { 66 | return _Vec3( -this->x,-this->y,-z ); 67 | } 68 | _Vec3& operator=( const _Vec3 &rhs ) 69 | { 70 | this->x = rhs.x; 71 | this->y = rhs.y; 72 | z = rhs.z; 73 | return *this; 74 | } 75 | _Vec3& operator+=( const _Vec3 &rhs ) 76 | { 77 | this->x += rhs.x; 78 | this->y += rhs.y; 79 | z += rhs.z; 80 | return *this; 81 | } 82 | _Vec3& operator-=( const _Vec3 &rhs ) 83 | { 84 | this->x -= rhs.x; 85 | this->y -= rhs.y; 86 | z -= rhs.z; 87 | return *this; 88 | } 89 | T operator*( const _Vec3 &rhs ) const 90 | { 91 | return this->x * rhs.x + this->y * rhs.y + z * rhs.z; 92 | } 93 | _Vec3 operator+( const _Vec3 &rhs ) const 94 | { 95 | return _Vec3( *this ) += rhs; 96 | } 97 | _Vec3 operator-( const _Vec3 &rhs ) const 98 | { 99 | return _Vec3( *this ) -= rhs; 100 | } 101 | _Vec3& operator*=( const T &rhs ) 102 | { 103 | this->x *= rhs; 104 | this->y *= rhs; 105 | z *= rhs; 106 | return *this; 107 | } 108 | _Vec3 operator*( const T &rhs ) const 109 | { 110 | return _Vec3( *this ) *= rhs; 111 | } 112 | _Vec3 operator%( const _Vec3& rhs ) const 113 | { 114 | return _Vec3( 115 | this->y * rhs.z - z * rhs.y, 116 | z * rhs.x - this->x * rhs.z, 117 | this->x * rhs.y - this->y * rhs.x ); 118 | } 119 | _Vec3& operator/=( const T &rhs ) 120 | { 121 | this->x /= rhs; 122 | this->y /= rhs; 123 | z /= rhs; 124 | return *this; 125 | } 126 | _Vec3 operator/( const T &rhs ) const 127 | { 128 | return _Vec3( *this ) /= rhs; 129 | } 130 | bool operator==( const _Vec3 &rhs ) const 131 | { 132 | return this->x == rhs.x && this->y == rhs.y && rhs.z == z; 133 | } 134 | bool operator!=( const _Vec3 &rhs ) const 135 | { 136 | return !(*this == rhs); 137 | } 138 | // clamp to between 0.0 ~ 1.0 139 | _Vec3& Saturate() 140 | { 141 | this->x = std::min( 1.0f,std::max( 0.0f, this->x ) ); 142 | this->y = std::min( 1.0f,std::max( 0.0f, this->y ) ); 143 | z = std::min( 1.0f,std::max( 0.0f,z ) ); 144 | return *this; 145 | } 146 | // clamp to between 0.0 ~ 1.0 147 | _Vec3 GetSaturated() const 148 | { 149 | _Vec3 temp( *this ); 150 | temp.Saturate(); 151 | return temp; 152 | } 153 | // x3 = x1 * x2 etc. 154 | _Vec3& Hadamard( const _Vec3& rhs ) 155 | { 156 | this->x *= rhs.x; 157 | this->y *= rhs.y; 158 | z *= rhs.z; 159 | return *this; 160 | } 161 | // x3 = x1 * x2 etc. 162 | _Vec3 GetHadamard( const _Vec3& rhs ) const 163 | { 164 | _Vec3 temp( *this ); 165 | temp.Hadamard( rhs ); 166 | return temp; 167 | } 168 | public: 169 | T z; 170 | }; 171 | 172 | typedef _Vec3 Vec3; 173 | typedef _Vec3 Ved3; 174 | typedef _Vec3 Vei3; -------------------------------------------------------------------------------- /Engine/VertexFlatEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | 7 | // flat shading with vertex normals 8 | class VertexFlatEffect 9 | { 10 | public: 11 | // the vertex type that will be input into the pipeline 12 | class Vertex 13 | { 14 | public: 15 | Vertex() = default; 16 | Vertex( const Vec3& pos ) 17 | : 18 | pos( pos ) 19 | {} 20 | Vertex( const Vec3& pos,const Vertex& src ) 21 | : 22 | n( src.n ), 23 | pos( pos ) 24 | {} 25 | Vertex( const Vec3& pos,const Vec3& n ) 26 | : 27 | n( n ), 28 | pos( pos ) 29 | {} 30 | Vertex& operator+=( const Vertex& rhs ) 31 | { 32 | pos += rhs.pos; 33 | return *this; 34 | } 35 | Vertex operator+( const Vertex& rhs ) const 36 | { 37 | return Vertex( *this ) += rhs; 38 | } 39 | Vertex& operator-=( const Vertex& rhs ) 40 | { 41 | pos -= rhs.pos; 42 | return *this; 43 | } 44 | Vertex operator-( const Vertex& rhs ) const 45 | { 46 | return Vertex( *this ) -= rhs; 47 | } 48 | Vertex& operator*=( float rhs ) 49 | { 50 | pos *= rhs; 51 | return *this; 52 | } 53 | Vertex operator*( float rhs ) const 54 | { 55 | return Vertex( *this ) *= rhs; 56 | } 57 | Vertex& operator/=( float rhs ) 58 | { 59 | pos /= rhs; 60 | return *this; 61 | } 62 | Vertex operator/( float rhs ) const 63 | { 64 | return Vertex( *this ) /= rhs; 65 | } 66 | public: 67 | Vec3 pos; 68 | Vec3 n; 69 | }; 70 | // calculate color based on normal to light angle 71 | // no interpolation of color attribute 72 | class VertexShader 73 | { 74 | public: 75 | class Output 76 | { 77 | public: 78 | Output() = default; 79 | Output( const Vec3& pos ) 80 | : 81 | pos( pos ) 82 | {} 83 | Output( const Vec3& pos,const Output& src ) 84 | : 85 | color( src.color ), 86 | pos( pos ) 87 | {} 88 | Output( const Vec3& pos,const Color& color ) 89 | : 90 | color( color ), 91 | pos( pos ) 92 | {} 93 | Output& operator+=( const Output& rhs ) 94 | { 95 | pos += rhs.pos; 96 | return *this; 97 | } 98 | Output operator+( const Output& rhs ) const 99 | { 100 | return Output( *this ) += rhs; 101 | } 102 | Output& operator-=( const Output& rhs ) 103 | { 104 | pos -= rhs.pos; 105 | return *this; 106 | } 107 | Output operator-( const Output& rhs ) const 108 | { 109 | return Output( *this ) -= rhs; 110 | } 111 | Output& operator*=( float rhs ) 112 | { 113 | pos *= rhs; 114 | return *this; 115 | } 116 | Output operator*( float rhs ) const 117 | { 118 | return Output( *this ) *= rhs; 119 | } 120 | Output& operator/=( float rhs ) 121 | { 122 | pos /= rhs; 123 | return *this; 124 | } 125 | Output operator/( float rhs ) const 126 | { 127 | return Output( *this ) /= rhs; 128 | } 129 | public: 130 | Vec3 pos; 131 | Color color; 132 | }; 133 | public: 134 | void BindRotation( const Mat3& rotation_in ) 135 | { 136 | rotation = rotation_in; 137 | } 138 | void BindTranslation( const Vec3& translation_in ) 139 | { 140 | translation = translation_in; 141 | } 142 | Output operator()( const Vertex& v ) const 143 | { 144 | // calculate intensity based on angle of incidence 145 | const auto d = diffuse * std::max( 0.0f,-(v.n * rotation) * dir ); 146 | // add diffuse+ambient, filter by material color, saturate and scale 147 | const auto c = color.GetHadamard( d + ambient ).Saturate() * 255.0f; 148 | return{ v.pos * rotation + translation,Color( c ) }; 149 | } 150 | void SetDiffuseLight( const Vec3& c ) 151 | { 152 | diffuse = { c.x,c.y,c.z }; 153 | } 154 | void SetAmbientLight( const Vec3& c ) 155 | { 156 | ambient = { c.x,c.y,c.z }; 157 | } 158 | void SetLightDirection( const Vec3& dl ) 159 | { 160 | assert( dl.LenSq() >= 0.001f ); 161 | dir = dl.GetNormalized(); 162 | } 163 | void SetMaterialColor( Color c ) 164 | { 165 | color = Vec3( c ); 166 | } 167 | private: 168 | Mat3 rotation; 169 | Vec3 translation; 170 | Vec3 dir = { 0.0f,0.0f,1.0f }; 171 | Vec3 diffuse = { 1.0f,1.0f,1.0f }; 172 | Vec3 ambient = { 0.1f,0.1f,0.1f }; 173 | Vec3 color = { 0.8f,0.85f,1.0f }; 174 | }; 175 | // default gs passes vertices through and outputs triangle 176 | typedef DefaultGeometryShader GeometryShader; 177 | // invoked for each pixel of a triangle 178 | // takes an input of attributes that are the 179 | // result of interpolating vertex attributes 180 | // and outputs a color 181 | class PixelShader 182 | { 183 | public: 184 | template 185 | Color operator()( const Input& in ) const 186 | { 187 | return in.color; 188 | } 189 | }; 190 | public: 191 | VertexShader vs; 192 | GeometryShader gs; 193 | PixelShader ps; 194 | }; -------------------------------------------------------------------------------- /Engine/RippleVertexSpecularPhongEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "BaseVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | #include "BasePhongShader.h" 7 | 8 | // flat shading with vertex normals 9 | template 10 | class RippleVertexSpecularPhongEffect 11 | { 12 | public: 13 | // the vertex type that will be input into the pipeline 14 | class Vertex 15 | { 16 | public: 17 | Vertex() = default; 18 | Vertex( const Vec3& pos ) 19 | : 20 | pos( pos ) 21 | {} 22 | Vertex( const Vec3& pos,const Vertex& src ) 23 | : 24 | t( src.t ), 25 | pos( pos ) 26 | {} 27 | Vertex( const Vec3& pos,const Vec2& t ) 28 | : 29 | t( t ), 30 | pos( pos ) 31 | {} 32 | public: 33 | Vec3 pos; 34 | Vec2 t; 35 | }; 36 | // vertex shader 37 | // output interpolates position, normal, world position 38 | class VSOutput 39 | { 40 | public: 41 | VSOutput() = default; 42 | VSOutput( const Vec4& pos ) 43 | : 44 | pos( pos ) 45 | {} 46 | VSOutput( const Vec4& pos,const VSOutput& src ) 47 | : 48 | n( src.n ), 49 | worldPos( src.worldPos ), 50 | pos( pos ), 51 | t( src.t ) 52 | {} 53 | VSOutput( const Vec4& pos,const Vec3& n,const Vec3& worldPos,const Vec2& t ) 54 | : 55 | n( n ), 56 | pos( pos ), 57 | worldPos( worldPos ), 58 | t( t ) 59 | {} 60 | VSOutput& operator+=( const VSOutput& rhs ) 61 | { 62 | pos += rhs.pos; 63 | n += rhs.n; 64 | worldPos += rhs.worldPos; 65 | t += rhs.t; 66 | return *this; 67 | } 68 | VSOutput operator+( const VSOutput& rhs ) const 69 | { 70 | return VSOutput( *this ) += rhs; 71 | } 72 | VSOutput& operator-=( const VSOutput& rhs ) 73 | { 74 | pos -= rhs.pos; 75 | n -= rhs.n; 76 | worldPos -= rhs.worldPos; 77 | t -= rhs.t; 78 | return *this; 79 | } 80 | VSOutput operator-( const VSOutput& rhs ) const 81 | { 82 | return VSOutput( *this ) -= rhs; 83 | } 84 | VSOutput& operator*=( float rhs ) 85 | { 86 | pos *= rhs; 87 | n *= rhs; 88 | worldPos *= rhs; 89 | t *= rhs; 90 | return *this; 91 | } 92 | VSOutput operator*( float rhs ) const 93 | { 94 | return VSOutput( *this ) *= rhs; 95 | } 96 | VSOutput& operator/=( float rhs ) 97 | { 98 | pos /= rhs; 99 | n /= rhs; 100 | worldPos /= rhs; 101 | t /= rhs; 102 | return *this; 103 | } 104 | VSOutput operator/( float rhs ) const 105 | { 106 | return VSOutput( *this ) /= rhs; 107 | } 108 | public: 109 | Vec4 pos; 110 | Vec3 n; 111 | Vec3 worldPos; 112 | Vec2 t; 113 | }; 114 | class VertexShader : public BaseVertexShader 115 | { 116 | public: 117 | void SetTime( float time ) 118 | { 119 | t = time; 120 | } 121 | typename BaseVertexShader::Output operator()( const Vertex& v ) const 122 | { 123 | // calculate some triggy bois 124 | const auto angle = wrap_angle( v.pos.x * freq + t * wavelength ); 125 | const auto cosx = std::cos( angle ); 126 | const auto sinx = std::sin( angle ); 127 | // sine wave amplitude from position w/ time variant phase animation 128 | const auto dz = amplitude * cosx; 129 | const auto pos = Vec4{ v.pos.x,v.pos.y,v.pos.z + dz,1.0f }; 130 | // normal derived base on cross product of partial dx x dy 131 | auto n = Vec4{ 132 | -freq * amplitude * sinx, 133 | 0.0f, 134 | -1.0f, 135 | 0.0f 136 | }; 137 | n.Normalize(); 138 | 139 | return { pos * this->worldViewProj,n * this->worldView,pos * this->worldView,v.t }; 140 | } 141 | private: 142 | static constexpr float wavelength = PI; 143 | static constexpr float freq = 45.0f; 144 | static constexpr float amplitude = 0.02f; 145 | float t = 0.0f; 146 | }; 147 | // default gs passes vertices through and outputs triangle 148 | typedef DefaultGeometryShader GeometryShader; 149 | // invoked for each pixel of a triangle 150 | // takes an input of attributes that are the 151 | // result of interpolating vertex attributes 152 | // and outputs a color 153 | class PixelShader : public BasePhongShader 154 | { 155 | public: 156 | template 157 | Color operator()( const Input& in ) const 158 | { 159 | const auto material_color = Vec3( pTex->GetPixel( 160 | static_cast( in.t.x * tex_width + 0.5f ) % tex_width, 161 | static_cast( in.t.y * tex_height + 0.5f ) % tex_width 162 | ) ) / 255.0f; 163 | return this->Shade( in,material_color ); 164 | } 165 | void BindTexture( const Surface& tex ) 166 | { 167 | pTex = &tex; 168 | tex_width = pTex->GetWidth(); 169 | tex_height = pTex->GetHeight(); 170 | } 171 | private: 172 | const Surface* pTex = nullptr; 173 | unsigned int tex_width; 174 | unsigned int tex_height; 175 | }; 176 | public: 177 | VertexShader vs; 178 | GeometryShader gs; 179 | PixelShader ps; 180 | }; -------------------------------------------------------------------------------- /Engine/GouraudEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultGeometryShader.h" 5 | 6 | // flat shading with vertex normals 7 | class GouraudEffect 8 | { 9 | public: 10 | // the vertex type that will be input into the pipeline 11 | class Vertex 12 | { 13 | public: 14 | Vertex() = default; 15 | Vertex( const Vec3& pos ) 16 | : 17 | pos( pos ) 18 | {} 19 | Vertex( const Vec3& pos,const Vertex& src ) 20 | : 21 | n( src.n ), 22 | pos( pos ) 23 | {} 24 | Vertex( const Vec3& pos,const Vec3& n ) 25 | : 26 | n( n ), 27 | pos( pos ) 28 | {} 29 | Vertex& operator+=( const Vertex& rhs ) 30 | { 31 | pos += rhs.pos; 32 | return *this; 33 | } 34 | Vertex operator+( const Vertex& rhs ) const 35 | { 36 | return Vertex( *this ) += rhs; 37 | } 38 | Vertex& operator-=( const Vertex& rhs ) 39 | { 40 | pos -= rhs.pos; 41 | return *this; 42 | } 43 | Vertex operator-( const Vertex& rhs ) const 44 | { 45 | return Vertex( *this ) -= rhs; 46 | } 47 | Vertex& operator*=( float rhs ) 48 | { 49 | pos *= rhs; 50 | return *this; 51 | } 52 | Vertex operator*( float rhs ) const 53 | { 54 | return Vertex( *this ) *= rhs; 55 | } 56 | Vertex& operator/=( float rhs ) 57 | { 58 | pos /= rhs; 59 | return *this; 60 | } 61 | Vertex operator/( float rhs ) const 62 | { 63 | return Vertex( *this ) /= rhs; 64 | } 65 | public: 66 | Vec3 pos; 67 | Vec3 n; 68 | }; 69 | // calculate color based on normal to light angle 70 | // no interpolation of color attribute 71 | class VertexShader 72 | { 73 | public: 74 | class Output 75 | { 76 | public: 77 | Output() = default; 78 | Output( const Vec3& pos ) 79 | : 80 | pos( pos ) 81 | {} 82 | Output( const Vec3& pos,const Output& src ) 83 | : 84 | color( src.color ), 85 | pos( pos ) 86 | {} 87 | Output( const Vec3& pos,const Vec3& color ) 88 | : 89 | color( color ), 90 | pos( pos ) 91 | {} 92 | Output& operator+=( const Output& rhs ) 93 | { 94 | pos += rhs.pos; 95 | color += rhs.color; 96 | return *this; 97 | } 98 | Output operator+( const Output& rhs ) const 99 | { 100 | return Output( *this ) += rhs; 101 | } 102 | Output& operator-=( const Output& rhs ) 103 | { 104 | pos -= rhs.pos; 105 | color -= rhs.color; 106 | return *this; 107 | } 108 | Output operator-( const Output& rhs ) const 109 | { 110 | return Output( *this ) -= rhs; 111 | } 112 | Output& operator*=( float rhs ) 113 | { 114 | pos *= rhs; 115 | color *= rhs; 116 | return *this; 117 | } 118 | Output operator*( float rhs ) const 119 | { 120 | return Output( *this ) *= rhs; 121 | } 122 | Output& operator/=( float rhs ) 123 | { 124 | pos /= rhs; 125 | color /= rhs; 126 | return *this; 127 | } 128 | Output operator/( float rhs ) const 129 | { 130 | return Output( *this ) /= rhs; 131 | } 132 | public: 133 | Vec3 pos; 134 | Vec3 color; 135 | }; 136 | public: 137 | void BindRotation( const Mat3& rotation_in ) 138 | { 139 | rotation = rotation_in; 140 | } 141 | void BindTranslation( const Vec3& translation_in ) 142 | { 143 | translation = translation_in; 144 | } 145 | Output operator()( const Vertex& v ) const 146 | { 147 | // calculate intensity based on angle of incidence 148 | const auto d = diffuse * std::max( 0.0f,-(v.n * rotation) * dir ); 149 | // add diffuse+ambient, filter by material color, saturate and scale 150 | const auto c = color.GetHadamard( d + ambient ).Saturate() * 255.0f; 151 | return{ v.pos * rotation + translation,c }; 152 | } 153 | void SetDiffuseLight( const Vec3& c ) 154 | { 155 | diffuse = { c.x,c.y,c.z }; 156 | } 157 | void SetAmbientLight( const Vec3& c ) 158 | { 159 | ambient = { c.x,c.y,c.z }; 160 | } 161 | void SetLightDirection( const Vec3& dl ) 162 | { 163 | assert( dl.LenSq() >= 0.001f ); 164 | dir = dl.GetNormalized(); 165 | } 166 | void SetMaterialColor( Color c ) 167 | { 168 | color = Vec3( c ); 169 | } 170 | private: 171 | Mat3 rotation; 172 | Vec3 translation; 173 | Vec3 dir = { 0.0f,0.0f,1.0f }; 174 | Vec3 diffuse = { 1.0f,1.0f,1.0f }; 175 | Vec3 ambient = { 0.1f,0.1f,0.1f }; 176 | Vec3 color = { 0.8f,0.85f,1.0f }; 177 | }; 178 | // default gs passes vertices through and outputs triangle 179 | typedef DefaultGeometryShader GeometryShader; 180 | // invoked for each pixel of a triangle 181 | // takes an input of attributes that are the 182 | // result of interpolating vertex attributes 183 | // and outputs a color 184 | class PixelShader 185 | { 186 | public: 187 | template 188 | Color operator()( const Input& in ) const 189 | { 190 | return Color( in.color ); 191 | } 192 | }; 193 | public: 194 | VertexShader vs; 195 | GeometryShader gs; 196 | PixelShader ps; 197 | }; -------------------------------------------------------------------------------- /Engine/VertexLightTexturedEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "BaseVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | #include "BasePhongShader.h" 7 | 8 | 9 | // flat shading with vertex normals 10 | template 11 | class VertexLightTexturedEffect 12 | { 13 | public: 14 | // the vertex type that will be input into the pipeline 15 | class Vertex 16 | { 17 | public: 18 | Vertex() = default; 19 | Vertex( const Vec4& pos ) 20 | : 21 | pos( pos ) 22 | {} 23 | Vertex( const Vec4& pos,const Vertex& src ) 24 | : 25 | n( src.n ), 26 | pos( pos ) 27 | {} 28 | Vertex( const Vec4& pos,const Vec3& n ) 29 | : 30 | n( n ), 31 | pos( pos ) 32 | {} 33 | public: 34 | Vec4 pos; 35 | Vec3 n; 36 | Vec2 t; 37 | }; 38 | // vertex shader 39 | // output interpolates position, light, and tex coord 40 | class VSOutput 41 | { 42 | public: 43 | VSOutput() = default; 44 | VSOutput( const Vec4& pos ) 45 | : 46 | pos( pos ) 47 | {} 48 | VSOutput( const Vec4& pos,const VSOutput& src ) 49 | : 50 | t( src.t ), 51 | l( src.l ), 52 | pos( pos ) 53 | {} 54 | VSOutput( const Vec4& pos,const Vec2& t,const Vec3& l ) 55 | : 56 | t( t ), 57 | pos( pos ), 58 | l( l ) 59 | {} 60 | VSOutput& operator+=( const VSOutput& rhs ) 61 | { 62 | pos += rhs.pos; 63 | t += rhs.t; 64 | l += rhs.l; 65 | return *this; 66 | } 67 | VSOutput operator+( const VSOutput& rhs ) const 68 | { 69 | return VSOutput( *this ) += rhs; 70 | } 71 | VSOutput& operator-=( const VSOutput& rhs ) 72 | { 73 | pos -= rhs.pos; 74 | t -= rhs.t; 75 | l -= rhs.l; 76 | return *this; 77 | } 78 | VSOutput operator-( const VSOutput& rhs ) const 79 | { 80 | return VSOutput( *this ) -= rhs; 81 | } 82 | VSOutput& operator*=( float rhs ) 83 | { 84 | pos *= rhs; 85 | t *= rhs; 86 | l *= rhs; 87 | return *this; 88 | } 89 | VSOutput operator*( float rhs ) const 90 | { 91 | return VSOutput( *this ) *= rhs; 92 | } 93 | VSOutput& operator/=( float rhs ) 94 | { 95 | pos /= rhs; 96 | t /= rhs; 97 | l /= rhs; 98 | return *this; 99 | } 100 | VSOutput operator/( float rhs ) const 101 | { 102 | return VSOutput( *this ) /= rhs; 103 | } 104 | public: 105 | Vec4 pos; 106 | Vec2 t; 107 | Vec3 l; 108 | }; 109 | class VertexShader : public BaseVertexShader 110 | { 111 | public: 112 | using Output = VSOutput; 113 | public: 114 | Output operator()( const Vertex& v ) const 115 | { 116 | // transform mech vertex position before lighting calc 117 | const auto worldPos = v.pos * this->worldView; 118 | // vertex to light data 119 | const auto v_to_l = light_pos - worldPos; 120 | const auto dist = v_to_l.Len(); 121 | const Vec3 dir = v_to_l / dist; 122 | // calculate attenuation 123 | const auto attenuation = 1.0f / 124 | (Diffuse::constant_attenuation + Diffuse::linear_attenuation * dist * Diffuse::quadradic_attenuation * sq( dist )); 125 | // calculate intensity based on angle of incidence and attenuation 126 | const auto d = light_diffuse * attenuation * std::max( 0.0f,static_cast( Vec4( v.n,0.0f ) * this->worldView ) * dir ); 127 | // add diffuse+ambient, filter by material color, saturate and scale 128 | const auto l = d + light_ambient; 129 | return{ v.pos * this->worldViewProj,v.t,l }; 130 | } 131 | void SetDiffuseLight( const Vec3& c ) 132 | { 133 | light_diffuse = c; 134 | } 135 | void SetAmbientLight( const Vec3& c ) 136 | { 137 | light_ambient = c; 138 | } 139 | void SetLightPosition( const Vec4& pos_in ) 140 | { 141 | light_pos = pos_in; 142 | } 143 | private: 144 | Vec3 light_diffuse; 145 | Vec3 light_ambient; 146 | Vec4 light_pos; 147 | }; 148 | // default gs passes vertices through and outputs triangle 149 | typedef DefaultGeometryShader GeometryShader; 150 | // invoked for each pixel of a triangle 151 | // takes an input of attributes that are the 152 | // result of interpolating vertex attributes 153 | // and outputs a color 154 | class PixelShader 155 | { 156 | public: 157 | template 158 | Color operator()( const Input& in ) const 159 | { 160 | const auto material_color = Vec3( pTex->GetPixel( 161 | static_cast( in.t.x * tex_width + 0.5f ) % tex_width, 162 | static_cast( in.t.y * tex_height + 0.5f ) % tex_width 163 | ) ) / 255.0f; 164 | return Color( material_color.GetHadamard( in.l ).GetSaturated() * 255.0f ); 165 | } 166 | void BindTexture( const Surface& tex ) 167 | { 168 | pTex = &tex; 169 | tex_width = pTex->GetWidth(); 170 | tex_height = pTex->GetHeight(); 171 | } 172 | private: 173 | const Surface* pTex = nullptr; 174 | unsigned int tex_width; 175 | unsigned int tex_height; 176 | }; 177 | public: 178 | VertexShader vs; 179 | GeometryShader gs; 180 | PixelShader ps; 181 | }; 182 | -------------------------------------------------------------------------------- /Engine/Surface.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Surface.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include "ChiliWin.h" 23 | #include "Colors.h" 24 | #include "Rect.h" 25 | #include "ChiliException.h" 26 | #include 27 | #include 28 | #include 29 | 30 | 31 | class Surface 32 | { 33 | public: 34 | class Exception : public ChiliException 35 | { 36 | public: 37 | using ChiliException::ChiliException; 38 | virtual std::wstring GetFullMessage() const override { return GetNote() + L"\nAt: " + GetLocation(); } 39 | virtual std::wstring GetExceptionType() const override { return L"Surface Exception"; } 40 | }; 41 | public: 42 | Surface( unsigned int width,unsigned int height,unsigned int pitch ) 43 | : 44 | pBuffer( std::make_unique( pitch * height ) ), 45 | width( width ), 46 | height( height ), 47 | pitch( pitch ) 48 | {} 49 | Surface( unsigned int width,unsigned int height ) 50 | : 51 | Surface( width,height,width ) 52 | {} 53 | Surface( Surface&& source ) 54 | : 55 | pBuffer( std::move( source.pBuffer ) ), 56 | width( source.width ), 57 | height( source.height ), 58 | pitch( source.pitch ) 59 | {} 60 | Surface( Surface& ) = delete; 61 | Surface& operator=( Surface&& donor ) 62 | { 63 | width = donor.width; 64 | height = donor.height; 65 | pitch = donor.pitch; 66 | pBuffer = std::move( donor.pBuffer ); 67 | donor.pBuffer = nullptr; 68 | return *this; 69 | } 70 | Surface& operator=( const Surface& ) = delete; 71 | ~Surface() 72 | {} 73 | void Clear( Color fillValue ) 74 | { 75 | memset( pBuffer.get(),fillValue.dword,pitch * height * sizeof( Color ) ); 76 | } 77 | void Present( unsigned int dstPitch,BYTE* const pDst ) const 78 | { 79 | for( unsigned int y = 0; y < height; y++ ) 80 | { 81 | memcpy( &pDst[dstPitch * y],&pBuffer[pitch * y],sizeof(Color) * width ); 82 | } 83 | } 84 | void PutPixel( unsigned int x,unsigned int y,Color c ) 85 | { 86 | assert( x >= 0 ); 87 | assert( y >= 0 ); 88 | assert( x < width ); 89 | assert( y < height ); 90 | pBuffer[y * pitch + x] = c; 91 | } 92 | void PutPixelAlpha( unsigned int x,unsigned int y,Color c ); 93 | Color GetPixel( unsigned int x,unsigned int y ) const 94 | { 95 | assert( x >= 0 ); 96 | assert( y >= 0 ); 97 | assert( x < width ); 98 | assert( y < height ); 99 | return pBuffer[y * pitch + x]; 100 | } 101 | unsigned int GetWidth() const 102 | { 103 | return width; 104 | } 105 | unsigned int GetHeight() const 106 | { 107 | return height; 108 | } 109 | unsigned int GetPitch() const 110 | { 111 | return pitch; 112 | } 113 | Color* GetBufferPtr() 114 | { 115 | return pBuffer.get(); 116 | } 117 | const Color* GetBufferPtrConst() const 118 | { 119 | return pBuffer.get(); 120 | } 121 | static Surface FromFile( const std::wstring& name ); 122 | void Save( const std::wstring& filename ) const; 123 | void Copy( const Surface& src ); 124 | private: 125 | // calculate pixel pitch required for given byte aligment (must be multiple of 4 bytes) 126 | static unsigned int GetPitch( unsigned int width,unsigned int byteAlignment ) 127 | { 128 | assert( byteAlignment % 4 == 0 ); 129 | const unsigned int pixelAlignment = byteAlignment / sizeof( Color ); 130 | return width + ( pixelAlignment - width % pixelAlignment ) % pixelAlignment; 131 | } 132 | Surface( unsigned int width,unsigned int height,unsigned int pitch,std::unique_ptr pBufferParam ) 133 | : 134 | width( width ), 135 | height( height ), 136 | pBuffer( std::move( pBufferParam ) ), 137 | pitch( pitch ) 138 | {} 139 | private: 140 | std::unique_ptr pBuffer; 141 | unsigned int width; 142 | unsigned int height; 143 | unsigned int pitch; // pitch is in PIXELS, not bytes! 144 | }; -------------------------------------------------------------------------------- /Engine/Graphics.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Graphics.h * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | #include 23 | #include 24 | #include "GDIPlusManager.h" 25 | #include "ChiliException.h" 26 | #include "Surface.h" 27 | #include "Colors.h" 28 | #include "Vec2.h" 29 | #include "ZBuffer.h" 30 | 31 | #define CHILI_GFX_EXCEPTION( hr,note ) Graphics::Exception( hr,note,_CRT_WIDE(__FILE__),__LINE__ ) 32 | 33 | class Graphics 34 | { 35 | public: 36 | class Exception : public ChiliException 37 | { 38 | public: 39 | Exception( HRESULT hr,const std::wstring& note,const wchar_t* file,unsigned int line ); 40 | std::wstring GetErrorName() const; 41 | std::wstring GetErrorDescription() const; 42 | virtual std::wstring GetFullMessage() const override; 43 | virtual std::wstring GetExceptionType() const override; 44 | private: 45 | HRESULT hr; 46 | }; 47 | private: 48 | // vertex format for the framebuffer fullscreen textured quad 49 | struct FSQVertex 50 | { 51 | float x,y,z; // position 52 | float u,v; // texcoords 53 | }; 54 | public: 55 | Graphics( class HWNDKey& key ); 56 | Graphics( const Graphics& ) = delete; 57 | Graphics& operator=( const Graphics& ) = delete; 58 | void EndFrame(); 59 | void BeginFrame(); 60 | void PutPixel( int x,int y,int r,int g,int b ) 61 | { 62 | PutPixel( x,y,{ unsigned char( r ),unsigned char( g ),unsigned char( b ) } ); 63 | } 64 | void PutPixel( int x,int y,Color c ) 65 | { 66 | sysBuffer.PutPixel( x,y,c ); 67 | } 68 | ~Graphics(); 69 | void DrawLineDepth( ZBuffer& zb,Vec3& v0,Vec3& v1,Color c ) 70 | { 71 | float dx = v1.x - v0.x; 72 | float dy = v1.y - v0.y; 73 | 74 | if( dy == 0.0f && dx == 0.0f ) 75 | {} 76 | else if( abs( dy ) > abs( dx ) ) 77 | { 78 | if( dy < 0.0f ) 79 | { 80 | std::swap( v0,v1 ); 81 | dy = -dy; 82 | } 83 | 84 | const auto dv = (v1 - v0) / dy; 85 | for( auto v = v0; v.y < v1.y; v += dv ) 86 | { 87 | const auto x = int( v.x ); 88 | const auto y = int( v.y ); 89 | if( x < 0 || x >= Graphics::ScreenWidth || y < 0 || y >= Graphics::ScreenHeight ) 90 | { 91 | continue; 92 | } 93 | if( zb.TestAndSet( x,y,v.z ) ) 94 | { 95 | PutPixel( x,y,c ); 96 | } 97 | } 98 | } 99 | else 100 | { 101 | if( dx < 0.0f ) 102 | { 103 | std::swap( v0,v1 ); 104 | dx = -dx; 105 | } 106 | 107 | const auto dv = (v1 - v0) / dx; 108 | for( auto v = v0; v.x < v1.x; v += dv ) 109 | { 110 | const auto x = int( v.x ); 111 | const auto y = int( v.y ); 112 | if( x < 0 || x >= Graphics::ScreenWidth || y < 0 || y >= Graphics::ScreenHeight ) 113 | { 114 | continue; 115 | } 116 | if( zb.TestAndSet( x,y,v.z ) ) 117 | { 118 | PutPixel( x,y,c ); 119 | } 120 | } 121 | } 122 | } 123 | private: 124 | GDIPlusManager gdipMan; 125 | Microsoft::WRL::ComPtr pSwapChain; 126 | Microsoft::WRL::ComPtr pDevice; 127 | Microsoft::WRL::ComPtr pImmediateContext; 128 | Microsoft::WRL::ComPtr pRenderTargetView; 129 | Microsoft::WRL::ComPtr pSysBufferTexture; 130 | Microsoft::WRL::ComPtr pSysBufferTextureView; 131 | Microsoft::WRL::ComPtr pPixelShader; 132 | Microsoft::WRL::ComPtr pVertexShader; 133 | Microsoft::WRL::ComPtr pVertexBuffer; 134 | Microsoft::WRL::ComPtr pInputLayout; 135 | Microsoft::WRL::ComPtr pSamplerState; 136 | D3D11_MAPPED_SUBRESOURCE mappedSysBufferTexture; 137 | Surface sysBuffer; 138 | public: 139 | static constexpr unsigned int ScreenWidth = 640u; 140 | static constexpr unsigned int ScreenHeight = 480u; 141 | }; -------------------------------------------------------------------------------- /Engine/GeometryFlatEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultVertexShader.h" 5 | #include "DefaultGeometryShader.h" 6 | 7 | // flat shading with face normals calculated in gs 8 | class GeometryFlatEffect 9 | { 10 | public: 11 | // the vertex type that will be input into the pipeline 12 | class Vertex 13 | { 14 | public: 15 | Vertex() = default; 16 | Vertex( const Vec3& pos ) 17 | : 18 | pos( pos ) 19 | {} 20 | Vertex( const Vec3& pos,const Vertex& src ) 21 | : 22 | pos( pos ) 23 | {} 24 | Vertex& operator+=( const Vertex& rhs ) 25 | { 26 | pos += rhs.pos; 27 | return *this; 28 | } 29 | Vertex operator+( const Vertex& rhs ) const 30 | { 31 | return Vertex( *this ) += rhs; 32 | } 33 | Vertex& operator-=( const Vertex& rhs ) 34 | { 35 | pos -= rhs.pos; 36 | return *this; 37 | } 38 | Vertex operator-( const Vertex& rhs ) const 39 | { 40 | return Vertex( *this ) -= rhs; 41 | } 42 | Vertex& operator*=( float rhs ) 43 | { 44 | pos *= rhs; 45 | return *this; 46 | } 47 | Vertex operator*( float rhs ) const 48 | { 49 | return Vertex( *this ) *= rhs; 50 | } 51 | Vertex& operator/=( float rhs ) 52 | { 53 | pos /= rhs; 54 | return *this; 55 | } 56 | Vertex operator/( float rhs ) const 57 | { 58 | return Vertex( *this ) /= rhs; 59 | } 60 | public: 61 | Vec3 pos; 62 | }; 63 | // default vs rotates and translates vertices 64 | // does not touch attributes 65 | typedef DefaultVertexShader VertexShader; 66 | // calculate color based on face normal calculated from 67 | // cross product of geometry--no interpolation of color 68 | class GeometryShader 69 | { 70 | public: 71 | class Output 72 | { 73 | public: 74 | Output() = default; 75 | Output( const Vec3& pos ) 76 | : 77 | pos( pos ) 78 | {} 79 | Output( const Vec3& pos,const Output& src ) 80 | : 81 | color( src.color ), 82 | pos( pos ) 83 | {} 84 | Output( const Vec3& pos,const Color& color ) 85 | : 86 | color( color ), 87 | pos( pos ) 88 | {} 89 | Output& operator+=( const Output& rhs ) 90 | { 91 | pos += rhs.pos; 92 | return *this; 93 | } 94 | Output operator+( const Output& rhs ) const 95 | { 96 | return Output( *this ) += rhs; 97 | } 98 | Output& operator-=( const Output& rhs ) 99 | { 100 | pos -= rhs.pos; 101 | return *this; 102 | } 103 | Output operator-( const Output& rhs ) const 104 | { 105 | return Output( *this ) -= rhs; 106 | } 107 | Output& operator*=( float rhs ) 108 | { 109 | pos *= rhs; 110 | return *this; 111 | } 112 | Output operator*( float rhs ) const 113 | { 114 | return Output( *this ) *= rhs; 115 | } 116 | Output& operator/=( float rhs ) 117 | { 118 | pos /= rhs; 119 | return *this; 120 | } 121 | Output operator/( float rhs ) const 122 | { 123 | return Output( *this ) /= rhs; 124 | } 125 | public: 126 | Vec3 pos; 127 | Color color; 128 | }; 129 | public: 130 | Triangle operator()( const VertexShader::Output& in0,const VertexShader::Output& in1,const VertexShader::Output& in2,size_t triangle_index ) const 131 | { 132 | // calculate face normal 133 | const auto n = ((in1.pos - in0.pos) % (in2.pos - in0.pos)).GetNormalized(); 134 | // calculate intensity based on angle of incidence 135 | const auto d = diffuse * std::max( 0.0f,-n * dir ); 136 | // add diffuse+ambient, filter by material color, saturate and scale 137 | const auto c = Color( color.GetHadamard( d + ambient ).Saturate() * 255.0f ); 138 | return{ {in0.pos,c},{in1.pos,c},{in2.pos,c} }; 139 | } 140 | void SetDiffuseLight( const Vec3& c ) 141 | { 142 | diffuse = { c.x,c.y,c.z }; 143 | } 144 | void SetAmbientLight( const Vec3& c ) 145 | { 146 | ambient = { c.x,c.y,c.z }; 147 | } 148 | void SetLightDirection( const Vec3& dl ) 149 | { 150 | assert( dl.LenSq() >= 0.001f ); 151 | dir = dl.GetNormalized(); 152 | } 153 | void SetMaterialColor( Color c ) 154 | { 155 | color = Vec3( c ); 156 | } 157 | private: 158 | Mat3 rotation; 159 | Vec3 translation; 160 | Vec3 dir = { 0.0f,0.0f,1.0f }; 161 | // this is the intensity if direct light from source 162 | // color light so need values per color component 163 | Vec3 diffuse = { 1.0f,1.0f,1.0f }; 164 | // this is intensity of indirect light that bounces off other obj in scene 165 | // color light so need values per color component 166 | Vec3 ambient = { 0.1f,0.1f,0.1f }; 167 | // color of material (how much light of each color is reflected) 168 | Vec3 color = { 0.8f,0.85f,1.0f }; 169 | }; 170 | // invoked for each pixel of a triangle 171 | // takes an input of attributes that are the 172 | // result of interpolating vertex attributes 173 | // and outputs a color 174 | class PixelShader 175 | { 176 | public: 177 | template 178 | Color operator()( const Input& in ) const 179 | { 180 | return in.color; 181 | } 182 | }; 183 | public: 184 | VertexShader vs; 185 | GeometryShader gs; 186 | PixelShader ps; 187 | }; -------------------------------------------------------------------------------- /Engine/Vec4.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Vec2.h * 4 | * Copyright 2018 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #pragma once 22 | 23 | #include 24 | #include "ChiliMath.h" 25 | #include "Vec3.h" 26 | 27 | template 28 | class _Vec4 : public _Vec3 29 | { 30 | public: 31 | _Vec4() = default; 32 | _Vec4( T x,T y,T z,T w ) 33 | : 34 | _Vec3( x,y,z ), 35 | w( w ) 36 | {} 37 | _Vec4( const _Vec3& v3,float w = 1.0f ) 38 | : 39 | _Vec3( v3 ), 40 | w( w ) 41 | {} 42 | template 43 | explicit operator _Vec4() const 44 | { 45 | return{ (T2)this->x,(T2)this->y,(T2)this->z,(T2)w }; 46 | } 47 | //T LenSq() const 48 | //{ 49 | // return sq( *this ); 50 | //} 51 | //T Len() const 52 | //{ 53 | // return sqrt( LenSq() ); 54 | //} 55 | //_Vec3& Normalize() 56 | //{ 57 | // const T length = Len(); 58 | // x /= length; 59 | // y /= length; 60 | // z /= length; 61 | // return *this; 62 | //} 63 | //_Vec3 GetNormalized() const 64 | //{ 65 | // _Vec3 norm = *this; 66 | // norm.Normalize(); 67 | // return norm; 68 | //} 69 | _Vec4 operator-() const 70 | { 71 | return _Vec4( -this->x,-this->y,-this->z,-w ); 72 | } 73 | _Vec4& operator=( const _Vec4 &rhs ) 74 | { 75 | this->x = rhs.x; 76 | this->y = rhs.y; 77 | this->z = rhs.z; 78 | w = rhs.w; 79 | return *this; 80 | } 81 | _Vec4& operator+=( const _Vec4 &rhs ) 82 | { 83 | this->x += rhs.x; 84 | this->y += rhs.y; 85 | this->z += rhs.z; 86 | w += rhs.w; 87 | return *this; 88 | } 89 | _Vec4& operator-=( const _Vec4 &rhs ) 90 | { 91 | this->x -= rhs.x; 92 | this->y -= rhs.y; 93 | this->z -= rhs.z; 94 | w -= rhs.w; 95 | return *this; 96 | } 97 | //T operator*( const _Vec4 &rhs ) const 98 | //{ 99 | // return x * rhs.x + y * rhs.y + z * rhs.z; 100 | //} 101 | _Vec4 operator+( const _Vec4 &rhs ) const 102 | { 103 | return _Vec4( *this ) += rhs; 104 | } 105 | _Vec4 operator-( const _Vec4 &rhs ) const 106 | { 107 | return _Vec4( *this ) -= rhs; 108 | } 109 | _Vec4& operator*=( const T &rhs ) 110 | { 111 | this->x *= rhs; 112 | this->y *= rhs; 113 | this->z *= rhs; 114 | w *= rhs; 115 | return *this; 116 | } 117 | _Vec4 operator*( const T &rhs ) const 118 | { 119 | return _Vec4( *this ) *= rhs; 120 | } 121 | //_Vec4 operator%( const _Vec4& rhs ) const 122 | //{ 123 | // return _Vec4( 124 | // y * rhs.z - z * rhs.y, 125 | // z * rhs.x - x * rhs.z, 126 | // x * rhs.y - y * rhs.x ); 127 | //} 128 | _Vec4& operator/=( const T &rhs ) 129 | { 130 | this->x /= rhs; 131 | this->y /= rhs; 132 | this->z /= rhs; 133 | w /= rhs; 134 | return *this; 135 | } 136 | _Vec4 operator/( const T &rhs ) const 137 | { 138 | return _Vec4( *this ) /= rhs; 139 | } 140 | bool operator==( const _Vec4 &rhs ) const 141 | { 142 | return this->x == rhs.x && this->y == rhs.y && rhs.z == this->z && rhs.w == w; 143 | } 144 | bool operator!=( const _Vec4 &rhs ) const 145 | { 146 | return !(*this == rhs); 147 | } 148 | // clamp to between 0.0 ~ 1.0 149 | _Vec4& Saturate() 150 | { 151 | this->x = std::min( 1.0f,std::max( 0.0f, this->x ) ); 152 | this->y = std::min( 1.0f,std::max( 0.0f, this->y ) ); 153 | this->z = std::min( 1.0f,std::max( 0.0f, this->z ) ); 154 | w = std::min( 1.0f,std::max( 0.0f,w ) ); 155 | return *this; 156 | } 157 | // clamp to between 0.0 ~ 1.0 158 | _Vec4 GetSaturated() const 159 | { 160 | _Vec4 temp( *this ); 161 | temp.Saturate(); 162 | return temp; 163 | } 164 | // x3 = x1 * x2 etc. 165 | _Vec4& Hadamard( const _Vec4& rhs ) 166 | { 167 | this->x *= rhs.x; 168 | this->y *= rhs.y; 169 | this->z *= rhs.z; 170 | w *= rhs.w; 171 | return *this; 172 | } 173 | // x3 = x1 * x2 etc. 174 | _Vec4 GetHadamard( const _Vec4& rhs ) const 175 | { 176 | _Vec4 temp( *this ); 177 | temp.Hadamard( rhs ); 178 | return temp; 179 | } 180 | public: 181 | T w; 182 | }; 183 | 184 | typedef _Vec4 Vec4; 185 | typedef _Vec4 Ved4; 186 | typedef _Vec4 Vei4; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ 246 | 247 | ################# 248 | # Chili Ignores # 249 | ################# 250 | 251 | # Precompiled shader bytecode headers 252 | *.shh 253 | 254 | # .obj 3d model files unignore 255 | !Engine/models/*.obj -------------------------------------------------------------------------------- /Engine/GouraudPointEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultGeometryShader.h" 5 | 6 | // flat shading with vertex normals 7 | class GouraudPointEffect 8 | { 9 | public: 10 | // the vertex type that will be input into the pipeline 11 | class Vertex 12 | { 13 | public: 14 | Vertex() = default; 15 | Vertex( const Vec3& pos ) 16 | : 17 | pos( pos ) 18 | {} 19 | Vertex( const Vec3& pos,const Vertex& src ) 20 | : 21 | n( src.n ), 22 | pos( pos ) 23 | {} 24 | Vertex( const Vec3& pos,const Vec3& n ) 25 | : 26 | n( n ), 27 | pos( pos ) 28 | {} 29 | Vertex& operator+=( const Vertex& rhs ) 30 | { 31 | pos += rhs.pos; 32 | return *this; 33 | } 34 | Vertex operator+( const Vertex& rhs ) const 35 | { 36 | return Vertex( *this ) += rhs; 37 | } 38 | Vertex& operator-=( const Vertex& rhs ) 39 | { 40 | pos -= rhs.pos; 41 | return *this; 42 | } 43 | Vertex operator-( const Vertex& rhs ) const 44 | { 45 | return Vertex( *this ) -= rhs; 46 | } 47 | Vertex& operator*=( float rhs ) 48 | { 49 | pos *= rhs; 50 | return *this; 51 | } 52 | Vertex operator*( float rhs ) const 53 | { 54 | return Vertex( *this ) *= rhs; 55 | } 56 | Vertex& operator/=( float rhs ) 57 | { 58 | pos /= rhs; 59 | return *this; 60 | } 61 | Vertex operator/( float rhs ) const 62 | { 63 | return Vertex( *this ) /= rhs; 64 | } 65 | public: 66 | Vec3 pos; 67 | Vec3 n; 68 | }; 69 | // calculate color based on normal to light angle 70 | // no interpolation of color attribute 71 | class VertexShader 72 | { 73 | public: 74 | class Output 75 | { 76 | public: 77 | Output() = default; 78 | Output( const Vec3& pos ) 79 | : 80 | pos( pos ) 81 | {} 82 | Output( const Vec3& pos,const Output& src ) 83 | : 84 | color( src.color ), 85 | pos( pos ) 86 | {} 87 | Output( const Vec3& pos,const Vec3& color ) 88 | : 89 | color( color ), 90 | pos( pos ) 91 | {} 92 | Output& operator+=( const Output& rhs ) 93 | { 94 | pos += rhs.pos; 95 | color += rhs.color; 96 | return *this; 97 | } 98 | Output operator+( const Output& rhs ) const 99 | { 100 | return Output( *this ) += rhs; 101 | } 102 | Output& operator-=( const Output& rhs ) 103 | { 104 | pos -= rhs.pos; 105 | color -= rhs.color; 106 | return *this; 107 | } 108 | Output operator-( const Output& rhs ) const 109 | { 110 | return Output( *this ) -= rhs; 111 | } 112 | Output& operator*=( float rhs ) 113 | { 114 | pos *= rhs; 115 | color *= rhs; 116 | return *this; 117 | } 118 | Output operator*( float rhs ) const 119 | { 120 | return Output( *this ) *= rhs; 121 | } 122 | Output& operator/=( float rhs ) 123 | { 124 | pos /= rhs; 125 | color /= rhs; 126 | return *this; 127 | } 128 | Output operator/( float rhs ) const 129 | { 130 | return Output( *this ) /= rhs; 131 | } 132 | public: 133 | Vec3 pos; 134 | Vec3 color; 135 | }; 136 | public: 137 | void BindRotation( const Mat3& rotation_in ) 138 | { 139 | rotation = rotation_in; 140 | } 141 | void BindTranslation( const Vec3& translation_in ) 142 | { 143 | translation = translation_in; 144 | } 145 | Output operator()( const Vertex& v ) const 146 | { 147 | // transform mech vertex position before lighting calc 148 | const auto pos = v.pos * rotation + translation; 149 | // vertex to light data 150 | const auto v_to_l = light_pos - pos; 151 | const auto dist = v_to_l.Len(); 152 | const auto dir = v_to_l / dist; 153 | // calculate attenuation 154 | const auto attenuation = 1.0f / 155 | (constant_attenuation + linear_attenuation * dist * quadradic_attenuation * sq( dist )); 156 | // calculate intensity based on angle of incidence and attenuation 157 | const auto d = light_diffuse * attenuation * std::max( 0.0f,(v.n * rotation) * dir ); 158 | // add diffuse+ambient, filter by material color, saturate and scale 159 | const auto c = material_color.GetHadamard( d + light_ambient ).Saturate() * 255.0f; 160 | return{ pos,c }; 161 | } 162 | void SetDiffuseLight( const Vec3& c ) 163 | { 164 | light_diffuse = c; 165 | } 166 | void SetAmbientLight( const Vec3& c ) 167 | { 168 | light_ambient = c; 169 | } 170 | void SetLightPosition( const Vec3& pos_in ) 171 | { 172 | light_pos = pos_in; 173 | } 174 | private: 175 | Mat3 rotation; 176 | Vec3 translation; 177 | Vec3 light_pos = { 0.0f,0.0f,0.5f }; 178 | Vec3 light_diffuse = { 1.0f,1.0f,1.0f }; 179 | Vec3 light_ambient = { 0.1f,0.1f,0.1f }; 180 | Vec3 material_color = { 0.8f,0.85f,1.0f }; 181 | float linear_attenuation = 1.0f; 182 | float quadradic_attenuation = 2.619f; 183 | float constant_attenuation = 0.382f; 184 | }; 185 | // default gs passes vertices through and outputs triangle 186 | typedef DefaultGeometryShader GeometryShader; 187 | // invoked for each pixel of a triangle 188 | // takes an input of attributes that are the 189 | // result of interpolating vertex attributes 190 | // and outputs a color 191 | class PixelShader 192 | { 193 | public: 194 | template 195 | Color operator()( const Input& in ) const 196 | { 197 | return Color( in.color ); 198 | } 199 | }; 200 | public: 201 | VertexShader vs; 202 | GeometryShader gs; 203 | PixelShader ps; 204 | }; -------------------------------------------------------------------------------- /Engine/Surface.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.10.01 * 3 | * Surface.cpp * 4 | * Copyright 2016 PlanetChili * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #define FULL_WINTARD 22 | #include "ChiliWin.h" 23 | #include "Surface.h" 24 | #include "ChiliException.h" 25 | namespace Gdiplus 26 | { 27 | using std::min; 28 | using std::max; 29 | } 30 | #include 31 | #include 32 | 33 | #pragma comment( lib,"gdiplus.lib" ) 34 | 35 | void Surface::PutPixelAlpha( unsigned int x,unsigned int y,Color c ) 36 | { 37 | assert( x >= 0 ); 38 | assert( y >= 0 ); 39 | assert( x < width ); 40 | assert( y < height ); 41 | // load source pixel 42 | const Color d = GetPixel( x,y ); 43 | 44 | // blend channels 45 | const unsigned char rsltRed = (c.GetR() * c.GetA() + d.GetR() * (255u - c.GetA())) / 256u; 46 | const unsigned char rsltGreen = (c.GetG() * c.GetA() + d.GetG() * (255u - c.GetA())) / 256u; 47 | const unsigned char rsltBlue = (c.GetB() * c.GetA() + d.GetB() * (255u - c.GetA())) / 256u; 48 | 49 | // pack channels back into pixel and fire pixel onto surface 50 | PutPixel( x,y,{ rsltRed,rsltGreen,rsltBlue } ); 51 | } 52 | 53 | Surface Surface::FromFile( const std::wstring & name ) 54 | { 55 | unsigned int width = 0; 56 | unsigned int height = 0; 57 | unsigned int pitch = 0; 58 | std::unique_ptr pBuffer = nullptr; 59 | 60 | { 61 | Gdiplus::Bitmap bitmap( name.c_str() ); 62 | if( bitmap.GetLastStatus() != Gdiplus::Status::Ok ) 63 | { 64 | std::wstringstream ss; 65 | ss << L"Loading image [" << name << L"]: failed to load."; 66 | throw Exception( _CRT_WIDE( __FILE__ ),__LINE__,ss.str() ); 67 | } 68 | 69 | pitch = width = bitmap.GetWidth(); 70 | height = bitmap.GetHeight(); 71 | pBuffer = std::make_unique( width * height ); 72 | 73 | for( unsigned int y = 0; y < height; y++ ) 74 | { 75 | for( unsigned int x = 0; x < width; x++ ) 76 | { 77 | Gdiplus::Color c; 78 | bitmap.GetPixel( x,y,&c ); 79 | pBuffer[y * pitch + x] = c.GetValue(); 80 | } 81 | } 82 | } 83 | 84 | return Surface( width,height,pitch,std::move( pBuffer ) ); 85 | } 86 | 87 | void Surface::Save( const std::wstring & filename ) const 88 | { 89 | auto GetEncoderClsid = [&filename]( const WCHAR* format,CLSID* pClsid ) -> void 90 | { 91 | UINT num = 0; // number of image encoders 92 | UINT size = 0; // size of the image encoder array in bytes 93 | 94 | Gdiplus::ImageCodecInfo* pImageCodecInfo = nullptr; 95 | 96 | Gdiplus::GetImageEncodersSize( &num,&size ); 97 | if( size == 0 ) 98 | { 99 | std::wstringstream ss; 100 | ss << L"Saving surface to [" << filename << L"]: failed to get encoder; size == 0."; 101 | throw Exception( _CRT_WIDE( __FILE__ ),__LINE__,ss.str() ); 102 | } 103 | 104 | pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc( size )); 105 | if( pImageCodecInfo == nullptr ) 106 | { 107 | std::wstringstream ss; 108 | ss << L"Saving surface to [" << filename << L"]: failed to get encoder; failed to allocate memory."; 109 | throw Exception( _CRT_WIDE( __FILE__ ),__LINE__,ss.str() ); 110 | } 111 | 112 | GetImageEncoders( num,size,pImageCodecInfo ); 113 | 114 | for( UINT j = 0; j < num; ++j ) 115 | { 116 | if( wcscmp( pImageCodecInfo[j].MimeType,format ) == 0 ) 117 | { 118 | *pClsid = pImageCodecInfo[j].Clsid; 119 | free( pImageCodecInfo ); 120 | return; 121 | } 122 | } 123 | 124 | free( pImageCodecInfo ); 125 | std::wstringstream ss; 126 | ss << L"Saving surface to [" << filename << 127 | L"]: failed to get encoder; failed to find matching encoder."; 128 | throw Exception( _CRT_WIDE( __FILE__ ),__LINE__,ss.str() ); 129 | }; 130 | 131 | CLSID bmpID; 132 | GetEncoderClsid( L"image/bmp",&bmpID ); 133 | Gdiplus::Bitmap bitmap( width,height,pitch * sizeof( Color ),PixelFormat32bppARGB,(BYTE*)pBuffer.get() ); 134 | if( bitmap.Save( filename.c_str(),&bmpID,nullptr ) != Gdiplus::Status::Ok ) 135 | { 136 | std::wstringstream ss; 137 | ss << L"Saving surface to [" << filename << L"]: failed to save."; 138 | throw Exception( _CRT_WIDE( __FILE__ ),__LINE__,ss.str() ); 139 | } 140 | } 141 | 142 | void Surface::Copy( const Surface & src ) 143 | { 144 | assert( width == src.width ); 145 | assert( height == src.height ); 146 | if( pitch == src.pitch ) 147 | { 148 | memcpy( pBuffer.get(),src.pBuffer.get(),pitch * height * sizeof( Color ) ); 149 | } 150 | else 151 | { 152 | for( unsigned int y = 0; y < height; y++ ) 153 | { 154 | memcpy( &pBuffer[pitch * y],&src.pBuffer[pitch * y],sizeof( Color )* width ); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /Engine/WaveVertexTextureEffect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Pipeline.h" 4 | #include "DefaultGeometryShader.h" 5 | 6 | class WaveVertexTextureEffect 7 | { 8 | public: 9 | class Vertex 10 | { 11 | public: 12 | Vertex() = default; 13 | Vertex( const Vec3& pos ) 14 | : 15 | pos( pos ) 16 | {} 17 | Vertex( const Vec3& pos,const Vertex& src ) 18 | : 19 | t( src.t ), 20 | pos( pos ) 21 | {} 22 | Vertex( const Vec3& pos,const Vec2& t ) 23 | : 24 | t( t ), 25 | pos( pos ) 26 | {} 27 | Vertex& operator+=( const Vertex& rhs ) 28 | { 29 | pos += rhs.pos; 30 | t += rhs.t; 31 | return *this; 32 | } 33 | Vertex operator+( const Vertex& rhs ) const 34 | { 35 | return Vertex( *this ) += rhs; 36 | } 37 | Vertex& operator-=( const Vertex& rhs ) 38 | { 39 | pos -= rhs.pos; 40 | t -= rhs.t; 41 | return *this; 42 | } 43 | Vertex operator-( const Vertex& rhs ) const 44 | { 45 | return Vertex( *this ) -= rhs; 46 | } 47 | Vertex& operator*=( float rhs ) 48 | { 49 | pos *= rhs; 50 | t *= rhs; 51 | return *this; 52 | } 53 | Vertex operator*( float rhs ) const 54 | { 55 | return Vertex( *this ) *= rhs; 56 | } 57 | Vertex& operator/=( float rhs ) 58 | { 59 | pos /= rhs; 60 | t /= rhs; 61 | return *this; 62 | } 63 | Vertex operator/( float rhs ) const 64 | { 65 | return Vertex( *this ) /= rhs; 66 | } 67 | public: 68 | Vec3 pos; 69 | Vec2 t; 70 | }; 71 | // perturbes vertices in y axis in sin wave based on 72 | // x position and time 73 | class VertexShader 74 | { 75 | public: 76 | typedef Vertex Output; 77 | public: 78 | void BindRotation( const Mat3& rotation_in ) 79 | { 80 | rotation = rotation_in; 81 | } 82 | void BindTranslation( const Vec3& translation_in ) 83 | { 84 | translation = translation_in; 85 | } 86 | Output operator()( const Vertex& in ) const 87 | { 88 | Vec3 pos = in.pos * rotation + translation; 89 | pos.y += amplitude * std::sin( time * freqScroll + pos.x * freqWave ); 90 | return{ pos,in.t }; 91 | } 92 | void SetTime( float t ) 93 | { 94 | time = t; 95 | } 96 | private: 97 | Mat3 rotation; 98 | Vec3 translation; 99 | float time = 0.0f; 100 | float freqWave = 10.0f; 101 | float freqScroll = 5.0f; 102 | float amplitude = 0.05f; 103 | }; 104 | // calculate lighting intensity based on light direction 105 | // and a face normal computed from geometry with cross product 106 | class GeometryShader 107 | { 108 | public: 109 | class Output 110 | { 111 | public: 112 | Output() = default; 113 | Output( const Vec3& pos ) 114 | : 115 | pos( pos ) 116 | {} 117 | Output( const Vec3& pos,const Output& src ) 118 | : 119 | t( src.t ), 120 | l( src.l ), 121 | pos( pos ) 122 | {} 123 | Output( const Vec3& pos,const Vec2& t,float l ) 124 | : 125 | t( t ), 126 | l( l ), 127 | pos( pos ) 128 | {} 129 | Output& operator+=( const Output& rhs ) 130 | { 131 | pos += rhs.pos; 132 | t += rhs.t; 133 | return *this; 134 | } 135 | Output operator+( const Output& rhs ) const 136 | { 137 | return Output( *this ) += rhs; 138 | } 139 | Output& operator-=( const Output& rhs ) 140 | { 141 | pos -= rhs.pos; 142 | t -= rhs.t; 143 | return *this; 144 | } 145 | Output operator-( const Output& rhs ) const 146 | { 147 | return Output( *this ) -= rhs; 148 | } 149 | Output& operator*=( float rhs ) 150 | { 151 | pos *= rhs; 152 | t *= rhs; 153 | return *this; 154 | } 155 | Output operator*( float rhs ) const 156 | { 157 | return Output( *this ) *= rhs; 158 | } 159 | Output& operator/=( float rhs ) 160 | { 161 | pos /= rhs; 162 | t /= rhs; 163 | return *this; 164 | } 165 | Output operator/( float rhs ) const 166 | { 167 | return Output( *this ) /= rhs; 168 | } 169 | public: 170 | Vec3 pos; 171 | Vec2 t; 172 | float l; 173 | }; 174 | public: 175 | Triangle operator()( const VertexShader::Output& in0,const VertexShader::Output& in1,const VertexShader::Output& in2,size_t triangle_index ) const 176 | { 177 | // calculate face normal 178 | const auto n = ((in1.pos - in0.pos) % (in2.pos - in0.pos)).GetNormalized(); 179 | // calculate intensity based on angle of incidence plus ambient and saturate 180 | const auto l = std::min( 1.0f,diffuse * std::max( 0.0f,-n * dir ) + ambient ); 181 | return{ { in0.pos,in0.t,l },{ in1.pos,in1.t,l },{ in2.pos,in2.t,l } }; 182 | } 183 | void SetDiffuseLight( float d ) 184 | { 185 | diffuse = d; 186 | } 187 | void SetAmbientLight( float a ) 188 | { 189 | ambient = a; 190 | } 191 | void SetLightDirection( const Vec3& dl ) 192 | { 193 | assert( dl.LenSq() >= 0.001f ); 194 | dir = dl.GetNormalized(); 195 | } 196 | private: 197 | Mat3 rotation; 198 | Vec3 translation; 199 | // direction of travel of light rays 200 | Vec3 dir = { 0.0f,0.0f,1.0f }; 201 | // this is the intensity if direct light from source 202 | // white light so only need 1 channel to represent it 203 | float diffuse = 1.0f; 204 | // this is intensity of indirect light that bounces off other obj in scene 205 | // white light so only need 1 channel to represent it 206 | float ambient = 0.15f; 207 | }; 208 | // texture clamped ps with light intensity input 209 | class PixelShader 210 | { 211 | public: 212 | template 213 | Color operator()( const Input& in ) const 214 | { 215 | // lookup color in texture 216 | const Vec3 color = Vec3( pTex->GetPixel( 217 | (unsigned int)std::min( in.t.x * tex_width + 0.5f,tex_xclamp ), 218 | (unsigned int)std::min( in.t.y * tex_height + 0.5f,tex_yclamp ) 219 | ) ); 220 | // use texture color as material to determine ratio / magnitude 221 | // of the different color components diffuse reflected from triangle at this pt. 222 | return Color( color * in.l ); 223 | } 224 | void BindTexture( const std::wstring& filename ) 225 | { 226 | pTex = std::make_unique( Surface::FromFile( filename ) ); 227 | tex_width = float( pTex->GetWidth() ); 228 | tex_height = float( pTex->GetHeight() ); 229 | tex_xclamp = tex_width - 1.0f; 230 | tex_yclamp = tex_height - 1.0f; 231 | } 232 | private: 233 | std::unique_ptr pTex; 234 | float tex_width; 235 | float tex_height; 236 | float tex_xclamp; 237 | float tex_yclamp; 238 | }; 239 | public: 240 | VertexShader vs; 241 | GeometryShader gs; 242 | PixelShader ps; 243 | }; -------------------------------------------------------------------------------- /Engine/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************************** 2 | * Chili DirectX Framework Version 16.07.20 * 3 | * MainWindow.cpp * 4 | * Copyright 2016 PlanetChili.net * 5 | * * 6 | * This file is part of The Chili DirectX Framework. * 7 | * * 8 | * The Chili DirectX Framework is free software: you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation, either version 3 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * The Chili DirectX Framework is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with The Chili DirectX Framework. If not, see . * 20 | ******************************************************************************************/ 21 | #include "MainWindow.h" 22 | #include "Resource.h" 23 | #include "Graphics.h" 24 | #include "ChiliException.h" 25 | #include "Game.h" 26 | #include 27 | 28 | MainWindow::MainWindow( HINSTANCE hInst,wchar_t * pArgs ) 29 | : 30 | args( pArgs ), 31 | hInst( hInst ) 32 | { 33 | // register window class 34 | WNDCLASSEX wc = { sizeof( WNDCLASSEX ),CS_CLASSDC,_HandleMsgSetup,0,0, 35 | hInst,nullptr,nullptr,nullptr,nullptr, 36 | wndClassName,nullptr }; 37 | wc.hIconSm = (HICON)LoadImage( hInst,MAKEINTRESOURCE( IDI_APPICON ),IMAGE_ICON,16,16,0 ); 38 | wc.hIcon = (HICON)LoadImage( hInst,MAKEINTRESOURCE( IDI_APPICON ),IMAGE_ICON,32,32,0 ); 39 | wc.hCursor = LoadCursor( nullptr,IDC_ARROW ); 40 | RegisterClassEx( &wc ); 41 | 42 | // create window & get hWnd 43 | RECT wr; 44 | wr.left = 350; 45 | wr.right = Graphics::ScreenWidth + wr.left; 46 | wr.top = 100; 47 | wr.bottom = Graphics::ScreenHeight + wr.top; 48 | AdjustWindowRect( &wr,WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,FALSE ); 49 | hWnd = CreateWindow( wndClassName,L"Chili DirectX Framework", 50 | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, 51 | wr.left,wr.top,wr.right - wr.left,wr.bottom - wr.top, 52 | nullptr,nullptr,hInst,this ); 53 | 54 | // throw exception if something went terribly wrong 55 | if( hWnd == nullptr ) 56 | { 57 | throw Exception( _CRT_WIDE( __FILE__ ),__LINE__, 58 | L"Failed to get valid window handle." ); 59 | } 60 | 61 | // show and update 62 | ShowWindow( hWnd,SW_SHOWDEFAULT ); 63 | UpdateWindow( hWnd ); 64 | } 65 | 66 | MainWindow::~MainWindow() 67 | { 68 | // unregister window class 69 | UnregisterClass( wndClassName,hInst ); 70 | } 71 | 72 | bool MainWindow::IsActive() const 73 | { 74 | return GetActiveWindow() == hWnd; 75 | } 76 | 77 | bool MainWindow::IsMinimized() const 78 | { 79 | return IsIconic( hWnd ) != 0; 80 | } 81 | 82 | void MainWindow::ShowMessageBox( const std::wstring& title,const std::wstring& message ) const 83 | { 84 | MessageBox( hWnd,message.c_str(),title.c_str(),MB_OK ); 85 | } 86 | 87 | bool MainWindow::ProcessMessage() 88 | { 89 | MSG msg; 90 | while( PeekMessage( &msg,nullptr,0,0,PM_REMOVE ) ) 91 | { 92 | TranslateMessage( &msg ); 93 | DispatchMessage( &msg ); 94 | if( msg.message == WM_QUIT ) 95 | { 96 | return false; 97 | } 98 | } 99 | return true; 100 | } 101 | 102 | LRESULT WINAPI MainWindow::_HandleMsgSetup( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) 103 | { 104 | // use create parameter passed in from CreateWindow() to store window class pointer at WinAPI side 105 | if( msg == WM_NCCREATE ) 106 | { 107 | // extract ptr to window class from creation data 108 | const CREATESTRUCTW* const pCreate = reinterpret_cast(lParam); 109 | MainWindow* const pWnd = reinterpret_cast(pCreate->lpCreateParams); 110 | // sanity check 111 | assert( pWnd != nullptr ); 112 | // set WinAPI-managed user data to store ptr to window class 113 | SetWindowLongPtr( hWnd,GWLP_USERDATA,reinterpret_cast(pWnd) ); 114 | // set message proc to normal (non-setup) handler now that setup is finished 115 | SetWindowLongPtr( hWnd,GWLP_WNDPROC,reinterpret_cast(&MainWindow::_HandleMsgThunk) ); 116 | // forward message to window class handler 117 | return pWnd->HandleMsg( hWnd,msg,wParam,lParam ); 118 | } 119 | // if we get a message before the WM_NCCREATE message, handle with default handler 120 | return DefWindowProc( hWnd,msg,wParam,lParam ); 121 | } 122 | 123 | LRESULT WINAPI MainWindow::_HandleMsgThunk( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) 124 | { 125 | // retrieve ptr to window class 126 | MainWindow* const pWnd = reinterpret_cast(GetWindowLongPtr( hWnd,GWLP_USERDATA )); 127 | // forward message to window class handler 128 | return pWnd->HandleMsg( hWnd,msg,wParam,lParam ); 129 | } 130 | 131 | LRESULT MainWindow::HandleMsg( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam ) 132 | { 133 | switch( msg ) 134 | { 135 | case WM_DESTROY: 136 | PostQuitMessage( 0 ); 137 | break; 138 | 139 | // ************ KEYBOARD MESSAGES ************ // 140 | case WM_KEYDOWN: 141 | if( !(lParam & 0x40000000) || kbd.AutorepeatIsEnabled() ) // no thank you on the autorepeat 142 | { 143 | kbd.OnKeyPressed( static_cast(wParam) ); 144 | } 145 | break; 146 | case WM_KEYUP: 147 | kbd.OnKeyReleased( static_cast(wParam) ); 148 | break; 149 | case WM_CHAR: 150 | kbd.OnChar( static_cast(wParam) ); 151 | break; 152 | // ************ END KEYBOARD MESSAGES ************ // 153 | 154 | // ************ MOUSE MESSAGES ************ // 155 | case WM_MOUSEMOVE: 156 | { 157 | POINTS pt = MAKEPOINTS( lParam ); 158 | if( pt.x > 0 && pt.x < Graphics::ScreenWidth && pt.y > 0 && pt.y < Graphics::ScreenHeight ) 159 | { 160 | mouse.OnMouseMove( pt.x,pt.y ); 161 | if( !mouse.IsInWindow() ) 162 | { 163 | SetCapture( hWnd ); 164 | mouse.OnMouseEnter(); 165 | } 166 | } 167 | else 168 | { 169 | if( wParam & (MK_LBUTTON | MK_RBUTTON) ) 170 | { 171 | pt.x = std::max( short( 0 ),pt.x ); 172 | pt.x = std::min( short( Graphics::ScreenWidth - 1 ),pt.x ); 173 | pt.y = std::max( short( 0 ),pt.y ); 174 | pt.y = std::min( short( Graphics::ScreenHeight - 1 ),pt.y ); 175 | mouse.OnMouseMove( pt.x,pt.y ); 176 | } 177 | else 178 | { 179 | ReleaseCapture(); 180 | mouse.OnMouseLeave(); 181 | mouse.OnLeftReleased( pt.x,pt.y ); 182 | mouse.OnRightReleased( pt.x,pt.y ); 183 | } 184 | } 185 | break; 186 | } 187 | case WM_LBUTTONDOWN: 188 | { 189 | const POINTS pt = MAKEPOINTS( lParam ); 190 | mouse.OnLeftPressed( pt.x,pt.y ); 191 | break; 192 | } 193 | case WM_RBUTTONDOWN: 194 | { 195 | const POINTS pt = MAKEPOINTS( lParam ); 196 | mouse.OnRightPressed( pt.x,pt.y ); 197 | break; 198 | } 199 | case WM_LBUTTONUP: 200 | { 201 | const POINTS pt = MAKEPOINTS( lParam ); 202 | mouse.OnLeftReleased( pt.x,pt.y ); 203 | break; 204 | } 205 | case WM_RBUTTONUP: 206 | { 207 | const POINTS pt = MAKEPOINTS( lParam ); 208 | mouse.OnRightReleased( pt.x,pt.y ); 209 | break; 210 | } 211 | case WM_MOUSEWHEEL: 212 | { 213 | const POINTS pt = MAKEPOINTS( lParam ); 214 | if( GET_WHEEL_DELTA_WPARAM( wParam ) > 0 ) 215 | { 216 | mouse.OnWheelUp( pt.x,pt.y ); 217 | } 218 | else if( GET_WHEEL_DELTA_WPARAM( wParam ) < 0 ) 219 | { 220 | mouse.OnWheelDown( pt.x,pt.y ); 221 | } 222 | break; 223 | } 224 | // ************ END MOUSE MESSAGES ************ // 225 | } 226 | 227 | return DefWindowProc( hWnd,msg,wParam,lParam ); 228 | } -------------------------------------------------------------------------------- /Engine/Cube.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Vec3.h" 4 | #include "IndexedTriangleList.h" 5 | 6 | class Cube 7 | { 8 | public: 9 | template 10 | static IndexedTriangleList GetPlain( float size = 1.0f ) 11 | { 12 | const float side = size / 2.0f; 13 | 14 | std::vector vertices; 15 | 16 | vertices.emplace_back( -side,-side,-side ); // 0 17 | vertices.emplace_back( side,-side,-side ); // 1 18 | vertices.emplace_back( -side,side,-side ); // 2 19 | vertices.emplace_back( side,side,-side ); // 3 20 | vertices.emplace_back( -side,-side,side ); // 4 21 | vertices.emplace_back( side,-side,side ); // 5 22 | vertices.emplace_back( -side,side,side ); // 6 23 | vertices.emplace_back( side,side,side ); // 7 24 | 25 | std::vector verts( vertices.size() ); 26 | for( size_t i = 0; i < vertices.size(); i++ ) 27 | { 28 | verts[i].pos = vertices[i]; 29 | } 30 | return{ 31 | std::move( verts ),{ 32 | 0,2,1, 2,3,1, 33 | 1,3,5, 3,7,5, 34 | 2,6,3, 3,6,7, 35 | 4,5,7, 4,7,6, 36 | 0,4,2, 2,4,6, 37 | 0,1,4, 1,5,4 38 | } 39 | }; 40 | } 41 | template 42 | static IndexedTriangleList GetPlainIndependentFaces( float size = 1.0f ) 43 | { 44 | const float side = size / 2.0f; 45 | 46 | std::vector vertices; 47 | 48 | vertices.emplace_back( -side,-side,-side ); // 0 near side 49 | vertices.emplace_back( side,-side,-side ); // 1 50 | vertices.emplace_back( -side,side,-side ); // 2 51 | vertices.emplace_back( side,side,-side ); // 3 52 | vertices.emplace_back( -side,-side,side ); // 4 far side 53 | vertices.emplace_back( side,-side,side ); // 5 54 | vertices.emplace_back( -side,side,side ); // 6 55 | vertices.emplace_back( side,side,side ); // 7 56 | vertices.emplace_back( -side,-side,-side ); // 8 left side 57 | vertices.emplace_back( -side,side,-side ); // 9 58 | vertices.emplace_back( -side,-side,side ); // 10 59 | vertices.emplace_back( -side,side,side ); // 11 60 | vertices.emplace_back( side,-side,-side ); // 12 right side 61 | vertices.emplace_back( side,side,-side ); // 13 62 | vertices.emplace_back( side,-side,side ); // 14 63 | vertices.emplace_back( side,side,side ); // 15 64 | vertices.emplace_back( -side,-side,-side ); // 16 bottom side 65 | vertices.emplace_back( side,-side,-side ); // 17 66 | vertices.emplace_back( -side,-side,side ); // 18 67 | vertices.emplace_back( side,-side,side ); // 19 68 | vertices.emplace_back( -side,side,-side ); // 20 top side 69 | vertices.emplace_back( side,side,-side ); // 21 70 | vertices.emplace_back( -side,side,side ); // 22 71 | vertices.emplace_back( side,side,side ); // 23 72 | 73 | std::vector verts( vertices.size() ); 74 | for( size_t i = 0; i < vertices.size(); i++ ) 75 | { 76 | verts[i].pos = vertices[i]; 77 | } 78 | return{ 79 | std::move( verts ),{ 80 | 0,2, 1, 2,3,1, 81 | 4,5, 7, 4,7,6, 82 | 8,10, 9, 10,11,9, 83 | 12,13,15, 12,15,14, 84 | 16,17,18, 18,17,19, 85 | 20,23,21, 20,22,23 86 | } 87 | }; 88 | } 89 | template 90 | static IndexedTriangleList GetIndependentFacesNormals( float size = 1.0f ) 91 | { 92 | // first generate cube vertex positions (independent faces) 93 | auto cube = GetPlainIndependentFaces( size ); 94 | 95 | // then for each vertex, add the normal (determined by inspection of cube) 96 | //vertices.emplace_back( -side,-side,-side ); // 0 near side 97 | //vertices.emplace_back( side,-side,-side ); // 1 98 | //vertices.emplace_back( -side,side,-side ); // 2 99 | //vertices.emplace_back( side,side,-side ); // 3 100 | cube.vertices[0].n = { 0.0f,0.0f,-1.0f }; 101 | cube.vertices[1].n = { 0.0f,0.0f,-1.0f }; 102 | cube.vertices[2].n = { 0.0f,0.0f,-1.0f }; 103 | cube.vertices[3].n = { 0.0f,0.0f,-1.0f }; 104 | //vertices.emplace_back( -side,-side,side ); // 4 far side 105 | //vertices.emplace_back( side,-side,side ); // 5 106 | //vertices.emplace_back( -side,side,side ); // 6 107 | //vertices.emplace_back( side,side,side ); // 7 108 | cube.vertices[4].n = { 0.0f,0.0f,1.0f }; 109 | cube.vertices[5].n = { 0.0f,0.0f,1.0f }; 110 | cube.vertices[6].n = { 0.0f,0.0f,1.0f }; 111 | cube.vertices[7].n = { 0.0f,0.0f,1.0f }; 112 | //vertices.emplace_back( -side,-side,-side ); // 8 left side 113 | //vertices.emplace_back( -side,side,-side ); // 9 114 | //vertices.emplace_back( -side,-side,side ); // 10 115 | //vertices.emplace_back( -side,side,side ); // 11 116 | cube.vertices[8].n = { -1.0f,0.0f,0.0f }; 117 | cube.vertices[9].n = { -1.0f,0.0f,0.0f }; 118 | cube.vertices[10].n = { -1.0f,0.0f,0.0f }; 119 | cube.vertices[11].n = { -1.0f,0.0f,0.0f }; 120 | //vertices.emplace_back( side,-side,-side ); // 12 right side 121 | //vertices.emplace_back( side,side,-side ); // 13 122 | //vertices.emplace_back( side,-side,side ); // 14 123 | //vertices.emplace_back( side,side,side ); // 15 124 | cube.vertices[12].n = { 1.0f,0.0f,0.0f }; 125 | cube.vertices[13].n = { 1.0f,0.0f,0.0f }; 126 | cube.vertices[14].n = { 1.0f,0.0f,0.0f }; 127 | cube.vertices[15].n = { 1.0f,0.0f,0.0f }; 128 | //vertices.emplace_back( -side,-side,-side ); // 16 bottom side 129 | //vertices.emplace_back( side,-side,-side ); // 17 130 | //vertices.emplace_back( -side,-side,side ); // 18 131 | //vertices.emplace_back( side,-side,side ); // 19 132 | cube.vertices[16].n = { 0.0f,-1.0f,0.0f }; 133 | cube.vertices[17].n = { 0.0f,-1.0f,0.0f }; 134 | cube.vertices[18].n = { 0.0f,-1.0f,0.0f }; 135 | cube.vertices[19].n = { 0.0f,-1.0f,0.0f }; 136 | //vertices.emplace_back( -side,side,-side ); // 20 top side 137 | //vertices.emplace_back( side,side,-side ); // 21 138 | //vertices.emplace_back( -side,side,side ); // 22 139 | //vertices.emplace_back( side,side,side ); // 23 140 | cube.vertices[20].n = { 0.0f,1.0f,0.0f }; 141 | cube.vertices[21].n = { 0.0f,1.0f,0.0f }; 142 | cube.vertices[22].n = { 0.0f,1.0f,0.0f }; 143 | cube.vertices[23].n = { 0.0f,1.0f,0.0f }; 144 | 145 | return cube; 146 | } 147 | template 148 | static IndexedTriangleList GetSkinned( float size = 1.0f ) 149 | { 150 | const float side = size / 2.0f; 151 | const auto ConvertTexCoord = []( float u,float v ) 152 | { 153 | return Vec2{ (u + 1.0f) / 3.0f,v / 4.0f }; 154 | }; 155 | 156 | std::vector vertices; 157 | std::vector tc; 158 | 159 | vertices.emplace_back( -side,-side,-side ); // 0 160 | tc.emplace_back( ConvertTexCoord( 1.0f,0.0f ) ); 161 | vertices.emplace_back( side,-side,-side ); // 1 162 | tc.emplace_back( ConvertTexCoord( 0.0f,0.0f ) ); 163 | vertices.emplace_back( -side,side,-side ); // 2 164 | tc.emplace_back( ConvertTexCoord( 1.0f,1.0f ) ); 165 | vertices.emplace_back( side,side,-side ); // 3 166 | tc.emplace_back( ConvertTexCoord( 0.0f,1.0f ) ); 167 | vertices.emplace_back( -side,-side,side ); // 4 168 | tc.emplace_back( ConvertTexCoord( 1.0f,3.0f ) ); 169 | vertices.emplace_back( side,-side,side ); // 5 170 | tc.emplace_back( ConvertTexCoord( 0.0f,3.0f ) ); 171 | vertices.emplace_back( -side,side,side ); // 6 172 | tc.emplace_back( ConvertTexCoord( 1.0f,2.0f ) ); 173 | vertices.emplace_back( side,side,side ); // 7 174 | tc.emplace_back( ConvertTexCoord( 0.0f,2.0f ) ); 175 | vertices.emplace_back( -side,-side,-side ); // 8 176 | tc.emplace_back( ConvertTexCoord( 1.0f,4.0f ) ); 177 | vertices.emplace_back( side,-side,-side ); // 9 178 | tc.emplace_back( ConvertTexCoord( 0.0f,4.0f ) ); 179 | vertices.emplace_back( -side,-side,-side ); // 10 180 | tc.emplace_back( ConvertTexCoord( 2.0f,1.0f ) ); 181 | vertices.emplace_back( -side,-side,side ); // 11 182 | tc.emplace_back( ConvertTexCoord( 2.0f,2.0f ) ); 183 | vertices.emplace_back( side,-side,-side ); // 12 184 | tc.emplace_back( ConvertTexCoord( -1.0f,1.0f ) ); 185 | vertices.emplace_back( side,-side,side ); // 13 186 | tc.emplace_back( ConvertTexCoord( -1.0f,2.0f ) ); 187 | 188 | std::vector verts( vertices.size() ); 189 | for( size_t i = 0; i < vertices.size(); i++ ) 190 | { 191 | verts[i].pos = vertices[i]; 192 | verts[i].t = tc[i]; 193 | } 194 | 195 | return{ 196 | std::move( verts ),{ 197 | 0,2,1, 2,3,1, 198 | 4,8,5, 5,8,9, 199 | 2,6,3, 3,6,7, 200 | 4,5,7, 4,7,6, 201 | 2,10,11, 2,11,6, 202 | 12,3,7, 12,7,13 203 | } 204 | }; 205 | } 206 | }; --------------------------------------------------------------------------------