diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index fe9c8b4..aa5304e 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -3,7 +3,7 @@ # # Add source to this project's executable. -add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp") +add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) @@ -26,7 +26,7 @@ endif() # "cacheVariables": { # "CMAKE_TOOLCHAIN_FILE": "{VCPKG_DIR}\\scripts\\buildsystems\\vcpkg.cmake" # } - +# find_package(directxtk CONFIG REQUIRED) -target_link_libraries(${PROJECT_NAME} D3d11.lib dxgi.lib Microsoft::DirectXTK) +target_link_libraries(${PROJECT_NAME} D3d11.lib dxgi.lib d3dcompiler.lib Microsoft::DirectXTK) diff --git a/framework/default.hpp b/framework/default.hpp new file mode 100644 index 0000000..a61bea7 --- /dev/null +++ b/framework/default.hpp @@ -0,0 +1,4 @@ +#include "../types.hpp" +#include "../forward.hpp" +#include "../xnaerror.hpp" +#include "../enums.hpp" \ No newline at end of file diff --git a/framework/forward.hpp b/framework/forward.hpp index fc4e37c..2372f5a 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -99,8 +99,12 @@ namespace xna { using PTexture = std::shared_ptr; class Texture2D; using PTexture2D = std::shared_ptr; + class Shader; + using PShader = std::shared_ptr; class VertexInputLayout; using PVertexInputLayout = std::shared_ptr; + class VertexShader; + using pVertexShader = std::shared_ptr; struct Viewport; using PViewport = std::shared_ptr; } diff --git a/framework/graphics/shader.hpp b/framework/graphics/shader.hpp new file mode 100644 index 0000000..ce5eb5b --- /dev/null +++ b/framework/graphics/shader.hpp @@ -0,0 +1,13 @@ +#ifndef XNA_GRAPHICS_SHADER_HPP +#define XNA_GRAPHICS_SHADER_HPP + +#include "../default.hpp" + +namespace xna { + class IShader { + public: + virtual ~IShader() {} + }; +} + +#endif \ No newline at end of file diff --git a/framework/graphics/vertexinput.hpp b/framework/graphics/vertexinput.hpp new file mode 100644 index 0000000..924d6d0 --- /dev/null +++ b/framework/graphics/vertexinput.hpp @@ -0,0 +1,13 @@ +#ifndef XNA_GRAPHICS_VERTEXINPUT_HPP +#define XNA_GRAPHICS_VERTEXINPUT_HPP + +#include "../default.hpp" + +namespace xna { + class IVertexInputLayout { + public: + virtual ~IVertexInputLayout(){} + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/dxheaders.hpp b/framework/platform/dxheaders.hpp new file mode 100644 index 0000000..133be21 --- /dev/null +++ b/framework/platform/dxheaders.hpp @@ -0,0 +1,3 @@ +#include "dxgi.h" +#include "d3d11.h" +#include \ No newline at end of file diff --git a/framework/platform/shader-dx.cpp b/framework/platform/shader-dx.cpp new file mode 100644 index 0000000..11c3adc --- /dev/null +++ b/framework/platform/shader-dx.cpp @@ -0,0 +1,89 @@ +#include "shader-dx.hpp" +#include "device-dx.hpp" + +namespace xna { + HRESULT Shader::CompileFromFile(LPCWSTR srcFile, LPCSTR entryPoint, LPCSTR profile, ID3DBlob** blob) + { + //https://learn.microsoft.com/en-us/windows/win32/direct3d11/how-to--compile-a-shader + + if (!srcFile || !entryPoint || !profile || !blob) + return E_INVALIDARG; + + *blob = nullptr; + + UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; +#if defined( DEBUG ) || defined( _DEBUG ) + flags |= D3DCOMPILE_DEBUG; +#endif + + const D3D_SHADER_MACRO defines[] = + { + "EXAMPLE_DEFINE", "1", + NULL, NULL + }; + + ID3DBlob* shaderBlob = nullptr; + ID3DBlob* errorBlob = nullptr; + HRESULT hr = D3DCompileFromFile(srcFile, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, + entryPoint, profile, + flags, 0, &shaderBlob, &errorBlob); + if (FAILED(hr)) + { + if (errorBlob) + { + OutputDebugStringA((char*)errorBlob->GetBufferPointer()); + errorBlob->Release(); + } + + if (shaderBlob) + shaderBlob->Release(); + + return hr; + } + + *blob = shaderBlob; + + return hr; + } + + bool VertexShader::Initialize(ID3DBlob* blob, xna_error_ptr_arg) { + if (!_device || !blob) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + const auto hr = _device->_device->CreateVertexShader( + blob->GetBufferPointer(), + blob->GetBufferSize(), + NULL, + &_vertexShader); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + return true; + } + + bool PixelShader::Initialize(ID3DBlob* blob, xna_error_ptr_arg) + { + if (!_device || !blob) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + const auto hr = _device->_device->CreatePixelShader( + blob->GetBufferPointer(), + blob->GetBufferSize(), + NULL, + &_pixelShader); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/framework/platform/shader-dx.hpp b/framework/platform/shader-dx.hpp new file mode 100644 index 0000000..6e31508 --- /dev/null +++ b/framework/platform/shader-dx.hpp @@ -0,0 +1,60 @@ +#ifndef XNA_PLATFORM_SHADER_DX_HPP +#define XNA_PLATFORM_SHADER_DX_HPP + +#include "../graphics/shader.hpp" +#include "dxheaders.hpp" + +namespace xna { + class Shader : public IShader { + public: + Shader(GraphicsDevice* device) : _device(device) { + } + + virtual ~Shader() override {} + + virtual bool Initialize(ID3DBlob* blob, xna_error_nullarg) = 0; + + static HRESULT CompileFromFile(_In_ LPCWSTR srcFile, _In_ LPCSTR entryPoint, _In_ LPCSTR profile, _Outptr_ ID3DBlob** blob); + + public: + GraphicsDevice* _device = nullptr; + }; + + class VertexShader : public Shader { + public: + VertexShader(GraphicsDevice* device) : + Shader(device) {} + + virtual ~VertexShader() override { + if (_vertexShader) { + _vertexShader->Release(); + _vertexShader = nullptr; + } + } + + virtual bool Initialize(ID3DBlob* blob, xna_error_nullarg) override; + + public: + ID3D11VertexShader* _vertexShader = nullptr; + }; + + class PixelShader : public Shader { + public: + PixelShader(GraphicsDevice* device) : + Shader(device) {} + + virtual ~PixelShader() override { + if (_pixelShader) { + _pixelShader->Release(); + _pixelShader = nullptr; + } + } + + virtual bool Initialize(ID3DBlob* blob, xna_error_nullarg) override; + + public: + ID3D11PixelShader* _pixelShader = nullptr; + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/shaders/pixel.hlsl b/framework/platform/shaders/pixel.hlsl new file mode 100644 index 0000000..d35f77b --- /dev/null +++ b/framework/platform/shaders/pixel.hlsl @@ -0,0 +1,38 @@ +/********************************************************************************** +// Pixel (Arquivo de Sombreamento) +// +// Criação: 11 Jul 2007 +// Atualização: 13 Ago 2021 +// Compilador: D3DCompiler +// +// Descrição: Define um pixel shader que apenas multiplica a cor do objeto +// pela cor da textura, depois de fazer uma amostragem linear +// ou anisotrópica +// +**********************************************************************************/ + + +Texture2D resource; + +SamplerState linearfilter +{ + Filter = MIN_MAG_MIP_LINEAR; +}; + +SamplerState anisotropic +{ + Filter = ANISOTROPIC; + MaxAnisotropy = 4; +}; + +struct pixelIn +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR; + float2 Tex : TEXCOORD; +}; + +float4 main(pixelIn pIn) : SV_TARGET +{ + return resource.Sample(linearfilter, pIn.Tex) * pIn.Color; +} \ No newline at end of file diff --git a/framework/platform/shaders/vertex.hlsl b/framework/platform/shaders/vertex.hlsl new file mode 100644 index 0000000..4786602 --- /dev/null +++ b/framework/platform/shaders/vertex.hlsl @@ -0,0 +1,50 @@ +/********************************************************************************** +// Vertex (Arquivo de Sombreamento) +// +// Criação: 11 Jul 2007 +// Atualização: 13 Ago 2021 +// Compilador: D3DCompiler +// +// Descrição: Define um vertex shader que apenas multiplica os vértices +// por uma matriz de transformação e projeção +// +**********************************************************************************/ + +// matriz de transformação e projeção +cbuffer ConstantBuffer +{ + float4x4 WorldViewProj; +} + +// estrutura dos vértices de entrada +struct VertexIn +{ + float3 Pos : POSITION; + float4 Color : COLOR; + float2 Tex : TEXCOORD; +}; + +// estrutura dos vértices de saída +struct VertexOut +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR; + float2 Tex : TEXCOORD; +}; + +// programa principal do vertex shader +VertexOut main(VertexIn vIn) +{ + VertexOut vOut; + + // transforma vértices para coordenadas da tela + vOut.Pos = mul(float4(vIn.Pos, 1.0f), WorldViewProj); + + // mantém as cores inalteradas + vOut.Color = vIn.Color; + + // mantém as coordenadas da textura inalteradas + vOut.Tex = vIn.Tex; + + return vOut; +} \ No newline at end of file diff --git a/framework/platform/vertexinput-dx.cpp b/framework/platform/vertexinput-dx.cpp new file mode 100644 index 0000000..7de6220 --- /dev/null +++ b/framework/platform/vertexinput-dx.cpp @@ -0,0 +1,28 @@ +#include "vertexinput-dx.hpp" +#include "device-dx.hpp" +#include +#include "dxgi.h" +#include "d3d11.h" + +namespace xna { + bool VertexInputLayout::Initialize(ID3DBlob* blob, xna_error_ptr_arg){ + if (!_device || !blob) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + const auto hr = _device->_device->CreateInputLayout( + _description.data(), + _description.size(), + blob->GetBufferPointer(), + blob->GetBufferSize(), + &_inputLayout); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/framework/platform/vertexinput-dx.hpp b/framework/platform/vertexinput-dx.hpp new file mode 100644 index 0000000..c97e379 --- /dev/null +++ b/framework/platform/vertexinput-dx.hpp @@ -0,0 +1,32 @@ +#ifndef XNA_PLATFORM_VERTEXINPUT_DX_HPP +#define XNA_PLATFORM_VERTEXINPUT_DX_HPP + +#include "../graphics/vertexinput.hpp" +#include "dxgi.h" +#include "d3d11.h" + +namespace xna { + class VertexInputLayout : public IVertexInputLayout { + public: + VertexInputLayout( + GraphicsDevice* device, + std::vector const& description) : + _device(device), _description(description){} + + virtual ~VertexInputLayout() override{ + if (_inputLayout) { + _inputLayout->Release(); + _inputLayout = nullptr; + } + } + + virtual bool Initialize(ID3DBlob* blob, xna_error_nullarg); + + public: + ID3D11InputLayout* _inputLayout{ nullptr }; + std::vector _description{}; + GraphicsDevice* _device = nullptr; + }; +} + +#endif \ No newline at end of file