diff --git a/CMakeLists.txt b/CMakeLists.txt index 01c7ea1..da49d69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,6 @@ project(WinApi) set(CMAKE_CXX_STANDARD 14) -add_executable(WinApi WIN32 main.cpp d3dx12.h DXWindow.cpp DXWindow.h Logger.cpp Logger.h utils.cpp utils.h Window.cpp Window.h Timer.cpp Timer.h IDrawable.h Geometry.h EventHandler.cpp EventHandler.h) +add_executable(WinApi WIN32 main.cpp d3dx12.h DXWindow.cpp DXWindow.h Logger.cpp Logger.h utils.cpp utils.h Window.cpp Window.h Timer.cpp Timer.h IDrawable.h Geometry.h EventHandler.cpp EventHandler.h Vertex.cpp Vertex.h) target_link_libraries(WinApi d3d12.lib dxgi.lib dxguid.lib d3dcompiler.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib) \ No newline at end of file diff --git a/DXWindow.cpp b/DXWindow.cpp index 2a111eb..78e3cd5 100644 --- a/DXWindow.cpp +++ b/DXWindow.cpp @@ -9,6 +9,8 @@ namespace eg3d { { init(); initDrawObjects(); + + rotAngle = 0.0f; } @@ -291,7 +293,6 @@ namespace eg3d { mCommandList->SetGraphicsRootConstantBufferView(0, cbResource->GetGPUVirtualAddress()); ////////// OBJEKTUMOK KIRAJZOLÁSA - //drawObject(); for (unsigned i = 0; i < drawables.size(); i++) { @@ -351,64 +352,22 @@ namespace eg3d { void DXWindow::initDrawObjects() { - initVertices(); setupInputLayout(); - createBuffers(); - uploadBuffers(); loadShaders(); createConstantBuffers(); createRootSignature(); createPSO(); } - - void DXWindow::initVertices() - { - vertices = { - { -0.5f, -0.5f, 0.1f, 1.0f, 0.0f, 0.0f }, - { 0.5f, -0.5f, 0.1f , 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.98f, 0.1f, 0.0f, 0.0f, 1.0f }, - }; - - indices = { 0, 2, 1 }; - } - void DXWindow::setupInputLayout() { inputElements = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0} + //{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0} // TODO további elemek létrehozása }; } - void DXWindow::createBuffers() - { - // --- vertex buffer létrehozása - vertexBuffer = createBuffer_UH(mDevice, vertices.size() * sizeof(Vertex)); - - vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); - vertexBufferView.StrideInBytes = sizeof(Vertex); - vertexBufferView.SizeInBytes = vertices.size() * sizeof(Vertex); - - // --- index buffer létrehozása TODO átírás createBuffer_UH() használatával - indexBuffer = createBuffer_UH(mDevice, indices.size() * sizeof(uint32_t)); - - indexBufferView.Format = DXGI_FORMAT_R32_UINT; - indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress(); - indexBufferView.SizeInBytes = indices.size() * sizeof(uint32_t); - } - - - void DXWindow::uploadBuffers() - { - // --- vertex buffer feltöltése - bufferMapCopy(vertexBuffer, vertices.data(), vertices.size() * sizeof(Vertex)); - - // --- index buffer feltöltése - bufferMapCopy(indexBuffer, indices.data(), indices.size() * sizeof(uint32_t)); - } - void DXWindow::createConstantBuffers() { cbResource = createBuffer_UH(mDevice, calc256AlignedSize(sizeof(constantBuffer))); @@ -418,7 +377,19 @@ namespace eg3d { { // transzformáció frissítése //DirectX::XMStoreFloat4x4(&constantBuffer.transformMatrix, DirectX::XMMatrixScaling(2.0, 1.0, 1.0)); - DirectX::XMStoreFloat4x4(&constantBuffer.transformMatrix, DirectX::XMMatrixRotationZ(XM_PI)); + + rotAngle = rotAngle - 0.01; + if (rotAngle > XM_2PI) + { + rotAngle -= XM_2PI; + } + + float viewHeight = 1.5; + DirectX::XMStoreFloat4x4(&constantBuffer.projMatrix, + //XMMatrixScaling(0.00001, 0.00001, 0.00001) * XMMatrixTranslation(0.0f, 0.0f, -100000.0f) * + DirectX::XMMatrixPerspectiveLH(viewHeight * getAspectRatio(), viewHeight, 0.5, 10)); + + DirectX::XMStoreFloat4x4(&constantBuffer.transformMatrix, DirectX::XMMatrixRotationZ(rotAngle)); bufferMapCopy(cbResource, static_cast(&constantBuffer), sizeof(constantBuffer)); } @@ -454,6 +425,8 @@ namespace eg3d { D3D12_GRAPHICS_PIPELINE_STATE_DESC psoD = {}; psoD.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); + //psoD.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + //psoD.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME; psoD.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); psoD.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); psoD.SampleMask = UINT_MAX; @@ -487,12 +460,4 @@ namespace eg3d { } } - void DXWindow::drawObject() - { - mCommandList->IASetVertexBuffers(0, 1, &vertexBufferView); - mCommandList->IASetIndexBuffer(&indexBufferView); - mCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - mCommandList->DrawIndexedInstanced(indices.size(), 1, 0, 0, 0); - } } diff --git a/DXWindow.h b/DXWindow.h index eec32f7..17affc1 100644 --- a/DXWindow.h +++ b/DXWindow.h @@ -16,17 +16,13 @@ #include -// Vertex struktúrája -struct Vertex -{ - float x, y, z; - float r, g, b; -}; +#include "Vertex.h" // konstansbuffer struktúrája struct ConstantBuffer { DirectX::XMFLOAT4X4 transformMatrix; + DirectX::XMFLOAT4X4 projMatrix; // vetítési mátrix }; namespace eg3d { @@ -92,18 +88,15 @@ namespace eg3d { ComPtr cbResource; // konstansbuffer DX-objektuma ConstantBuffer constantBuffer; // konstansbuffer // TODO TRANSZFORMÁCIÓS TULAJDONSÁGOK + float rotAngle; // forgatás szöge void initDrawObjects(); // kirajzolandó objektumok inicializálása - void initVertices(); // vertexek inicializálása void setupInputLayout(); // input layout beállítása - void createBuffers(); // bufferek elkészítése, tartalmuk betöltése - void uploadBuffers(); // bufferek feltöltése void loadShaders(); // shaderek betöltése void createConstantBuffers(); // konstansbufferek létrehozása void createRootSignature(); // root signature létrehozása void createPSO(); // PSO létrehozása - void drawObject(); // objektum kirajzolása void updateConstantBuffers(); // konstansbufferek frissítése diff --git a/Geometry.h b/Geometry.h index f5da651..400afd7 100644 --- a/Geometry.h +++ b/Geometry.h @@ -3,17 +3,25 @@ #include #include #include "IDrawable.h" +#include "Vertex.h" #include +using namespace DirectX; + namespace eg3d { - template + struct STLTriangle { + XMFLOAT3 normal; + XMFLOAT3 v1, v2, v3; + uint16_t attributeByteCount; + }; + class Geometry : public IDrawable { private: ComPtr mDevice; // device - std::vector mVertices; // vertexek + std::vector mVertices; // vertexek std::vector mIndices; // indexek std::mutex mModifMtx; // ... @@ -42,10 +50,10 @@ namespace eg3d { } // vertexek beállítása - void setVertices(const std::vector &vertices) { + void setVertices(const std::vector &vertices) { mVertices = vertices; - size_t bufferSize = mVertices.size() * sizeof(vertex_t); // buffer mérete + size_t bufferSize = mVertices.size() * sizeof(Vertex); // buffer mérete mVertexBuffer.Reset(); // buffer törlése mVertexBuffer = createBuffer_UH(mDevice, bufferSize); // buffer létrehozása @@ -53,12 +61,12 @@ namespace eg3d { // vertex buffer view beállítása mVertexBufferView.BufferLocation = mVertexBuffer->GetGPUVirtualAddress(); - mVertexBufferView.StrideInBytes = sizeof(vertex_t); + mVertexBufferView.StrideInBytes = sizeof(Vertex); mVertexBufferView.SizeInBytes = bufferSize; } // vertexek lekérése - std::vector getVertices() const { + std::vector getVertices() const { return mVertices; } @@ -109,9 +117,74 @@ namespace eg3d { setupInputAssembler(commandList); // input assembler beállítása commandList->DrawIndexedInstanced(mIndices.size(), 1, 0, 0, 0); // rajzolás } + + // két geometria egyesítése + Geometry& operator+=(const Geometry& other) + { + std::vector vertices = mVertices; + vertices.insert(vertices.end(), other.mVertices.begin(), other.mVertices.end()); + + uint32_t offset = mIndices.size() - 1; + std::vector indices = mIndices; + indices.insert(indices.end(), other.mIndices.begin(), other.mIndices.end()); + + // indexek megváltozatása offsettel + for (uint32_t i = offset + 1; i < indices.size(); i++) + { + indices[i] += offset; + } + + // bufferek újrafoglalása a videokártyán + setVertices(vertices); + setIndices(indices); + + return *this; + } + + // bináris STL fájl betöltése + void loadBinarySTL(const std::string& fileName) { + auto inFile = std::ifstream(fileName, std::ios::in | std::ios::binary); // bináris fájl megnyitása olvasásra + + if (!inFile.is_open()) { // megnézzük, hogy sikerült-e megnyitni a fájlt + LOG("Failed to open file: '" + fileName + "'! STL geometry loading failed!"); + return; + } + + // vertexek és indexek + std::vector vertices; + std::vector indices; + + uint32_t triN; // háromszögek száma + + inFile.seekg(80, std::ios::beg); // fejléc átugrása + inFile.read((char *)&triN, sizeof(triN)); // háromszögek számának kiolvasása + + // vertexek kiolvasása + for (uint32_t i = 0; i < triN; i++) { + STLTriangle triangle; + inFile.read((char *)&triangle, sizeof(triangle)); // egy háromszög betöltése + + vertices.push_back(triangle.v1); + vertices.push_back(triangle.v2); + vertices.push_back(triangle.v3); + + // indexek vektorának feltöltése + uint32_t firstIndex = 3 * i; + indices.push_back(firstIndex); + indices.push_back(firstIndex + 1); + indices.push_back(firstIndex + 2); + } + + inFile.close(); + + setVertices(vertices); + setIndices(indices); + + LOG("Successful geometry loading from file '" + fileName + "' of " + std::to_string(triN) + " triangles."); + } }; + // geometriatároló típusa - template - using GeometryPool = std::vector>>; + using GeometryPool = std::vector>; } diff --git a/RUNTIME/assets/crate.stl b/RUNTIME/assets/crate.stl new file mode 100644 index 0000000..e33ec1f Binary files /dev/null and b/RUNTIME/assets/crate.stl differ diff --git a/RUNTIME/shaders/basic_shader.hlsl b/RUNTIME/shaders/basic_shader.hlsl index 67c3e83..06c9fdc 100644 --- a/RUNTIME/shaders/basic_shader.hlsl +++ b/RUNTIME/shaders/basic_shader.hlsl @@ -1,7 +1,7 @@ struct VSInput // vertex shader bemeneti struktúra { float3 position_D : POSITION; - float3 color : COLOR; + //float3 color : COLOR; }; struct VSOutput // vertex shader kimeneti struktúra @@ -13,14 +13,15 @@ struct VSOutput // vertex shader kimeneti strukt cbuffer CBuf : register(b0) { float4x4 transformMatrix; + float4x4 projMatrix; }; VSOutput vs_main(VSInput input) { VSOutput output; // vertex shader kimenete - output.position_H = mul(transformMatrix, float4(input.position_D, 1.0)); - output.color = input.color; + output.position_H = mul(projMatrix, mul(transformMatrix, float4(input.position_D, 1.0))); + output.color = float3(1.0, 1.0, 1.0); return output; } diff --git a/Vertex.cpp b/Vertex.cpp new file mode 100644 index 0000000..3f803c8 --- /dev/null +++ b/Vertex.cpp @@ -0,0 +1,20 @@ +// +// Created by Epagris on 2020. 03. 14.. +// + +#include "Vertex.h" + +eg3d::Vertex::Vertex() : x(0.0f), y(0.0f), z(0.0f) {} + +eg3d::Vertex::Vertex(const DirectX::XMFLOAT3 xmf3) : x(xmf3.x), y(xmf3.y), z(xmf3.z) {} + +eg3d::Vertex::Vertex(std::initializer_list initList) { + if (initList.size() >= 3) { + const float *pParams = initList.begin(); + + // paraméterek elkérése + x = pParams[0]; + y = pParams[1]; + z = pParams[2]; + } +} \ No newline at end of file diff --git a/Vertex.h b/Vertex.h new file mode 100644 index 0000000..41f06a1 --- /dev/null +++ b/Vertex.h @@ -0,0 +1,26 @@ +// +// Created by Epagris on 2020. 03. 14.. +// + +#ifndef VERTEX +#define VERTEX + +#include +#include + +namespace eg3d { + + struct Vertex { + public: + float x, y, z; // koordináták + // float nx, ny, nz; // normálvektorok TODO + + Vertex(); // default konstruktor + Vertex(const DirectX::XMFLOAT3 xmf3); // betöltés XMFLOAT3-ból + Vertex(std::initializer_list initList); // konstruktor struktúraszerű inicializációval + }; + +} + + +#endif //VERTEX diff --git a/main.cpp b/main.cpp index 6bf69e4..3901dd7 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include "Timer.h" #include "Geometry.h" +#include "not_used/vertex_types.h" // FPS-mĂ©rĂ©s size_t gFrames = 0; @@ -38,31 +39,28 @@ int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszA gTmr1s.reg(timerCBData); std::vector vertices = { // vertexek - { -0.5f, -0.5f, 0.1f, 1.0f, 0.0f, 0.0f }, - { 0.5f, -0.5f, 0.1f , 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.98f, 0.1f, 0.0f, 0.0f, 1.0f }, + { -0.5f, -0.5f, 1.0f }, + { 0.5f, -0.5f, 1.0f }, + { 0.0f, 0.98f, 1.0f }, }; std::vector indices = { 0, 2, 1 }; // indexek - auto pGeo = std::shared_ptr>(new Geometry(win.getDevice())); + auto pGeo = std::shared_ptr(new Geometry(win.getDevice())); pGeo->setVertices(vertices); pGeo->setIndices(indices); + + auto pGeo2 = std::shared_ptr(new Geometry(win.getDevice())); + pGeo2->loadBinarySTL("assets/crate.stl"); + + //drawables.push_back(pGeo2); + //(*pGeo) += (*pGeo2); DrawablePool drawables; // geometriák halmaza drawables.push_back(pGeo); // pGeo geometria hozzáadása - vertices = { // vertexek - { -0.3f, -0.5f, 0.05f, 1.0f, 0.2f, 0.0f }, - { 0.3f, -0.5f, 0.05f , 0.2f, 1.0f, 0.0f }, - { 0.0f, 0.7f, 0.05f, 0.0f, 0.2f, 1.0f }, - }; - auto pGeo2 = std::shared_ptr>(new Geometry(win.getDevice())); - pGeo2->setVertices(vertices); - pGeo2->setIndices(indices); - - drawables.push_back(pGeo2); + // ------------------------------------ MSG msg = { };