diff --git a/enginecustom/Modellistclass.cpp b/enginecustom/Modellistclass.cpp new file mode 100644 index 0000000..ae3b3f2 --- /dev/null +++ b/enginecustom/Modellistclass.cpp @@ -0,0 +1,68 @@ +#include "modellistclass.h" + + +ModelListClass::ModelListClass() +{ + m_ModelInfoList = 0; +} + + +ModelListClass::ModelListClass(const ModelListClass& other) +{ +} + + +ModelListClass::~ModelListClass() +{ +} + + +void ModelListClass::Initialize(int numModels) +{ + int i; + + // Store the number of models. + m_modelCount = numModels; + + // Create a list array of the model information. + m_ModelInfoList = new ModelInfoType[m_modelCount]; + + // Seed the random generator with the current time. + srand((unsigned int)time(NULL)); + + // Go through all the models and randomly generate the position. + for (i = 0; i < m_modelCount; i++) + { + // Generate a random position in front of the viewer for the mode. + m_ModelInfoList[i].positionX = (((float)rand() - (float)rand()) / RAND_MAX) * 10.0f; + m_ModelInfoList[i].positionY = (((float)rand() - (float)rand()) / RAND_MAX) * 10.0f; + m_ModelInfoList[i].positionZ = ((((float)rand() - (float)rand()) / RAND_MAX) * 10.0f) + 5.0f; + } + + return; +} + +void ModelListClass::Shutdown() +{ + // Release the model information list. + if (m_ModelInfoList) + { + delete[] m_ModelInfoList; + m_ModelInfoList = 0; + } + + return; +} + +int ModelListClass::GetModelCount() +{ + return m_modelCount; +} + +void ModelListClass::GetData(int index, float& positionX, float& positionY, float& positionZ) +{ + positionX = m_ModelInfoList[index].positionX; + positionY = m_ModelInfoList[index].positionY; + positionZ = m_ModelInfoList[index].positionZ; + return; +} \ No newline at end of file diff --git a/enginecustom/Modellistclass.h b/enginecustom/Modellistclass.h new file mode 100644 index 0000000..17dcf10 --- /dev/null +++ b/enginecustom/Modellistclass.h @@ -0,0 +1,39 @@ +#ifndef _MODELLISTCLASS_H_ +#define _MODELLISTCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include + + +/////////////////////////////////////////////////////////////////////////////// +// Class name: ModelListClass +/////////////////////////////////////////////////////////////////////////////// +class ModelListClass +{ +private: + struct ModelInfoType + { + float positionX, positionY, positionZ; + }; + +public: + ModelListClass(); + ModelListClass(const ModelListClass&); + ~ModelListClass(); + + void Initialize(int); + void Shutdown(); + + int GetModelCount(); + void GetData(int, float&, float&, float&); + +private: + int m_modelCount; + ModelInfoType* m_ModelInfoList; +}; + +#endif diff --git a/enginecustom/Positionclass.cpp b/enginecustom/Positionclass.cpp new file mode 100644 index 0000000..1e66b88 --- /dev/null +++ b/enginecustom/Positionclass.cpp @@ -0,0 +1,202 @@ +#include "positionclass.h" + +PositionClass::PositionClass() +{ + m_frameTime = 0.0f; + m_rotationY = 0.0f; + m_rotationX = 0.0f; + m_positionX = 0.0f; + m_positionY = 0.0f; + m_positionZ = 0.0f; + m_leftTurnSpeed = 0.0f; + m_rightTurnSpeed = 0.0f; +} + + +PositionClass::PositionClass(const PositionClass& other) +{ +} + + +PositionClass::~PositionClass() +{ +} + +void PositionClass::SetFrameTime(float time) +{ + m_frameTime = time; + return; +} + +void PositionClass::GetRotation(float& y, float& x) +{ + y = m_rotationY; + x = m_rotationX; + return; +} + +void PositionClass::GetPosition(float& x, float& y, float& z) +{ + x = m_positionX; + y = m_positionY; + z = m_positionZ; + return; +} + +void PositionClass::TurnLeft(bool keydown) +{ + // If the key is pressed increase the speed at which the camera turns left. If not slow down the turn speed. + if (keydown) + { + m_leftTurnSpeed += m_frameTime * 1.5f; + + if (m_leftTurnSpeed > (m_frameTime * 200.0f)) + { + m_leftTurnSpeed = m_frameTime * 200.0f; + } + } + else + { + m_leftTurnSpeed -= m_frameTime * 1.0f; + + if (m_leftTurnSpeed < 0.0f) + { + m_leftTurnSpeed = 0.0f; + } + } + + // Update the rotation using the turning speed. + m_rotationY -= m_leftTurnSpeed; + if (m_rotationY < 0.0f) + { + m_rotationY += 360.0f; + } + + return; +} + + +void PositionClass::TurnRight(bool keydown) +{ + // If the key is pressed increase the speed at which the camera turns right. If not slow down the turn speed. + if (keydown) + { + m_rightTurnSpeed += m_frameTime * 1.5f; + + if (m_rightTurnSpeed > (m_frameTime * 200.0f)) + { + m_rightTurnSpeed = m_frameTime * 200.0f; + } + } + else + { + m_rightTurnSpeed -= m_frameTime * 1.0f; + + if (m_rightTurnSpeed < 0.0f) + { + m_rightTurnSpeed = 0.0f; + } + } + + // Update the rotation using the turning speed. + m_rotationY += m_rightTurnSpeed; + if (m_rotationY > 360.0f) + { + m_rotationY -= 360.0f; + } + + return; +} + +void PositionClass::TurnMouse(float deltaX, float deltaY) +{ + float speed = 0.1f; + // The turning speed is proportional to the horizontal mouse movement + m_horizontalTurnSpeed = deltaX * speed; + + // Update the rotation using the turning speed + m_rotationY += m_horizontalTurnSpeed; + if (m_rotationY < 0.0f) + { + m_rotationY += 360.0f; + } + else if (m_rotationY > 360.0f) + { + m_rotationY -= 360.0f; + } + + // The turning speed is proportional to the vertical mouse movement + m_verticalTurnSpeed = deltaY * speed; + + // Update the rotation using the turning speed + m_rotationX += m_verticalTurnSpeed; + if (m_rotationX < -90.0f) + { + m_rotationX = -90.0f; + } + else if (m_rotationX > 90.0f) + { + m_rotationX = 90.0f; + } + + return; +} + +void PositionClass::MoveCamera(bool forward, bool backward, bool left, bool right, bool up, bool down) +{ + float radiansY, radiansX; + float speed; + + // Set the speed of the camera. + speed = 2.0f * m_frameTime; + + // Convert degrees to radians. + radiansY = m_rotationY * 0.0174532925f; + radiansX = m_rotationX * 0.0174532925f; + + // Update the position. + + // If moving forward, the position moves in the direction of the camera and accordingly to its angle. + if (forward) + { + m_positionX += sinf(radiansY) * cosf(radiansX) * speed; + m_positionZ += cosf(radiansY) * cosf(radiansX) * speed; + m_positionY -= sinf(radiansX) * speed; + } + + // If moving backward, the position moves in the opposite direction of the camera and accordingly to its angle. + if (backward) + { + m_positionX -= sinf(radiansY) * cosf(radiansX) * speed; + m_positionZ -= cosf(radiansY) * cosf(radiansX) * speed; + m_positionY += sinf(radiansX) * speed; + } + + // If moving left, the position moves to the left of the camera and accordingly to its angle. + if (left) + { + m_positionX -= cosf(radiansY) * speed; + m_positionZ += sinf(radiansY) * speed; + } + + // If moving right, the position moves to the right of the camera and accordingly to its angle. + if (right) + { + m_positionX += cosf(radiansY) * speed; + m_positionZ -= sinf(radiansY) * speed; + } + + // If moving up, the position moves up. + if (up) + { + m_positionY += speed; + } + + // If moving down, the position moves down. + if (down) + { + m_positionY -= speed; + } + + return; +} \ No newline at end of file diff --git a/enginecustom/Positionclass.h b/enginecustom/Positionclass.h new file mode 100644 index 0000000..5048610 --- /dev/null +++ b/enginecustom/Positionclass.h @@ -0,0 +1,37 @@ +#ifndef _POSITIONCLASS_H_ +#define _POSITIONCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: PositionClass +//////////////////////////////////////////////////////////////////////////////// +class PositionClass +{ +public: + PositionClass(); + PositionClass(const PositionClass&); + ~PositionClass(); + + void SetFrameTime(float); + void GetRotation(float&, float&); + void GetPosition(float&, float&, float&); + + void TurnLeft(bool); + void TurnRight(bool); + void TurnMouse(float, float); + void MoveCamera(bool, bool, bool, bool, bool, bool); + +private: + float m_frameTime; + float m_rotationY, m_rotationX; + float m_positionX, m_positionY, m_positionZ; + float m_leftTurnSpeed, m_rightTurnSpeed, m_horizontalTurnSpeed, m_verticalTurnSpeed; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index c82f0ea..ed372d8 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -23,6 +23,14 @@ ApplicationClass::ApplicationClass() m_Fps = 0; m_FpsString = 0; m_ShaderManager = 0; + m_NormalMapShader = 0; + m_SpecMapShader = 0; + m_RenderCountString = 0; + m_ModelList = 0; + m_Position = 0; + m_Frustum = 0; + m_DisplayPlane = 0; + m_TranslateShader = 0; } @@ -40,12 +48,14 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) { char mouseString1[32], mouseString2[32], mouseString3[32]; char testString1[32], testString2[32], testString3[32]; - char modelFilename[128], textureFilename1[128], textureFilename2[128], textureFilename3[128]; + char modelFilename[128], textureFilename1[128], textureFilename2[128], textureFilename3[128], renderString[32]; char bitmapFilename[128]; char spriteFilename[128]; char fpsString[32]; bool result; + m_screenWidth = screenWidth; + m_screenHeight = screenHeight; // Create the Direct3D object. m_Direct3D = new D3DClass; @@ -72,6 +82,8 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) // Set the initial position of the camera. m_Camera->SetPosition(0.0f, 0.0f, -12.0f); m_Camera->SetRotation(0.0f, 0.0f, 0.0f); + m_Camera->Render(); + m_Camera->GetViewMatrix(m_baseViewMatrix); @@ -136,6 +148,25 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) return false; } + // Create and initialize the render to texture object. + m_RenderTexture = new RenderTextureClass; + + result = m_RenderTexture->Initialize(m_Direct3D->GetDevice(), 256, 256, SCREEN_DEPTH, SCREEN_NEAR, 1); + if (!result) + { + return false; + } + + // Create and initialize the display plane object. + m_DisplayPlane = new DisplayPlaneClass; + + result = m_DisplayPlane->Initialize(m_Direct3D->GetDevice(), 1.0f, 1.0f); + if (!result) + { + return false; + } + + // Set the sprite info file we will be using. strcpy_s(spriteFilename, "sprite_data_01.txt"); @@ -148,15 +179,6 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) return false; } - // Create and initialize the timer object. - m_Timer = new TimerClass; - - result = m_Timer->Initialize(); - if (!result) - { - return false; - } - // Set the initial mouse strings. strcpy_s(mouseString1, "Mouse X: 0"); strcpy_s(mouseString2, "Mouse Y: 0"); @@ -224,6 +246,16 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) return false; } + // Create and initialize the translate shader object. + m_TranslateShader = new TranslateShaderClass; + + result = m_TranslateShader->Initialize(m_Direct3D->GetDevice(), hwnd); + if (!result) + { + MessageBox(hwnd, L"Could not initialize the translate shader object.", L"Error", MB_OK); + return false; + } + // Create and initialize the light shader object. m_LightShader = new LightShaderClass; @@ -272,6 +304,56 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) return false; } + // Create and initialize the font shader object. + m_FontShader = new FontShaderClass; + + result = m_FontShader->Initialize(m_Direct3D->GetDevice(), hwnd); + if (!result) + { + MessageBox(hwnd, L"Could not initialize the font shader object.", L"Error", MB_OK); + return false; + } + + // Create and initialize the font object. + m_Font = new FontClass; + + result = m_Font->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), 0); + if (!result) + { + return false; + } + + // Set the initial render count string. + strcpy_s(renderString, "Render Count: 0"); + + // Create and initialize the text object for the render count string. + m_RenderCountString = new TextClass; + + result = m_RenderCountString->Initialize(m_Direct3D->GetDevice(), m_Direct3D->GetDeviceContext(), screenWidth, screenHeight, 32, m_Font, renderString, 10, 10, 1.0f, 1.0f, 1.0f); + if (!result) + { + return false; + } + + // Create and initialize the model list object. + m_ModelList = new ModelListClass; + m_ModelList->Initialize(25); + + // Create and initialize the timer object. + m_Timer = new TimerClass; + + result = m_Timer->Initialize(); + if (!result) + { + return false; + } + + // Create the position class object. + m_Position = new PositionClass; + + // Create the frustum class object. + m_Frustum = new FrustumClass; + // Create and initialize the fps object. m_Fps = new FpsClass(); @@ -303,6 +385,52 @@ void ApplicationClass::Shutdown() m_ShaderManager = 0; } + // Release the translate shader object. + if (m_TranslateShader) + { + m_TranslateShader->Shutdown(); + delete m_TranslateShader; + m_TranslateShader = 0; + } + + // Release the frustum class object. + if (m_Frustum) + { + delete m_Frustum; + m_Frustum = 0; + } + + // Release the display plane object. + if (m_DisplayPlane) + { + m_DisplayPlane->Shutdown(); + delete m_DisplayPlane; + m_DisplayPlane = 0; + } + + // Release the position object. + if (m_Position) + { + delete m_Position; + m_Position = 0; + } + + // Release the model list object. + if (m_ModelList) + { + m_ModelList->Shutdown(); + delete m_ModelList; + m_ModelList = 0; + } + + // Release the text objects for the render count string. + if (m_RenderCountString) + { + m_RenderCountString->Shutdown(); + delete m_RenderCountString; + m_RenderCountString = 0; + } + // Release the text objects for the mouse strings. if (m_MouseStrings) { @@ -456,21 +584,82 @@ void ApplicationClass::Shutdown() bool ApplicationClass::Frame(InputClass* Input) { - int mouseX, mouseY; - bool result, mouseDown; + int mouseX, mouseY, currentMouseX, currentMouseY; + bool result, mouseDown, keyDown, buttonQ, buttonD, buttonZ, buttonS, buttonA, buttonE; + float rotationY, rotationX, positionX, positionY, positionZ; + static float textureTranslation = 0.0f; float frameTime; + + static int lastMouseX = 0, lastMouseY = 0; + static float rotation = 360.0f; static float x = 0.f; static float y = 0.f; static float z = -8.f; + // Update the system stats. + m_Timer->Frame(); + + // Get the current frame time. + frameTime = m_Timer->GetTime(); + // Check if the user pressed escape and wants to exit the application. if (Input->IsEscapePressed()) { return false; } + // Get the location of the mouse from the input object, + Input->GetMouseLocation(mouseX, mouseY); + + currentMouseX = mouseX; + + float deltaX = currentMouseX - lastMouseX; // Calculez le d�placement de la souris + lastMouseX = currentMouseX; // Mettez � jour la derni�re position de la souris pour la prochaine image + + currentMouseY = mouseY; + + float deltaY = currentMouseY - lastMouseY; // Calculez le d�placement de la souris + lastMouseY = currentMouseY; // Mettez � jour la derni�re position de la souris pour la prochaine image + + // Set the frame time for calculating the updated position. + m_Position->SetFrameTime(m_Timer->GetTime()); + + // Check if the left or right arrow key has been pressed, if so rotate the camera accordingly. + keyDown = Input->IsLeftArrowPressed(); + m_Position->TurnLeft(keyDown); + + keyDown = Input->IsRightArrowPressed(); + m_Position->TurnRight(keyDown); + + m_Position->TurnMouse(deltaX, deltaY); + + // Get the current view point rotation. + m_Position->GetRotation(rotationY, rotationX); + + // Check if the a(q), d, w(z), s, q(a), e have been pressed, if so move the camera accordingly. + buttonQ = Input->IsAPressed(); + buttonD = Input->IsDPressed(); + buttonZ = Input->IsWPressed(); + buttonS = Input->IsSPressed(); + buttonA = Input->IsQPressed(); + buttonE = Input->IsEPressed(); + m_Position->MoveCamera(buttonZ, buttonS, buttonQ, buttonD, buttonE, buttonA); + m_Position->GetPosition(positionX, positionY, positionZ); + + // Set the postion and rotation of the camera. + m_Camera->SetPosition(positionX, positionY, positionZ); + m_Camera->SetRotation(rotationX, rotationY, 0.0f); + m_Camera->Render(); + + // Render the graphics scene. + result = Render(rotation, x, y, z, textureTranslation); + if (!result) + { + return false; + } + // Update the frames per second each frame. result = UpdateFps(); if (!result) @@ -493,17 +682,13 @@ bool ApplicationClass::Frame(InputClass* Input) //// Update the z position variable each frame. //z -= 0.0174532925f * 0.2f; - - // Render the graphics scene. - result = Render(rotation, x, y, z); + // Render the scene to a render texture. + result = RenderSceneToTexture(rotation); if (!result) { return false; } - // Get the location of the mouse from the input object, - Input->GetMouseLocation(mouseX, mouseY); - // Check if the mouse has been pressed. mouseDown = Input->IsMousePressed(); @@ -514,30 +699,76 @@ bool ApplicationClass::Frame(InputClass* Input) return false; } - // Update the system stats. - m_Timer->Frame(); - - // Get the current frame time. - frameTime = m_Timer->GetTime(); - // Update the sprite object using the frame time. m_Sprite->Update(frameTime); + // Increment the texture translation. + textureTranslation += 0.01f; + if (textureTranslation > 1.0f) + { + textureTranslation -= 1.0f; + } + + // Render the graphics scene. + result = Render(rotation, x, y, z, textureTranslation); + if (!result) + { + return false; + } + return true; } +bool ApplicationClass::RenderSceneToTexture(float rotation) +{ + XMMATRIX worldMatrix, viewMatrix, projectionMatrix; + bool result; -bool ApplicationClass::Render(float rotation, float x, float y, float z) + // Set the render target to be the render texture and clear it. + m_RenderTexture->SetRenderTarget(m_Direct3D->GetDeviceContext()); + m_RenderTexture->ClearRenderTarget(m_Direct3D->GetDeviceContext(), 0.0f, 0.5f, 1.0f, 1.0f); + + // Set the position of the camera for viewing the cube. + m_Camera->SetPosition(0.0f, 0.0f, -5.0f); + m_Camera->Render(); + + // Get the matrices. + m_Direct3D->GetWorldMatrix(worldMatrix); + m_Camera->GetViewMatrix(viewMatrix); + m_RenderTexture->GetProjectionMatrix(projectionMatrix); + + // Rotate the world matrix by the rotation value so that the cube will spin. + worldMatrix = XMMatrixRotationY(rotation); + + // Render the model using the texture shader. + m_Model->Render(m_Direct3D->GetDeviceContext()); + + result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(1)); + if (!result) + { + return false; + } + + // Reset the render target back to the original back buffer and not the render to texture anymore. And reset the viewport back to the original. + m_Direct3D->SetBackBufferRenderTarget(); + m_Direct3D->ResetViewport(); + + return true; +} + +bool ApplicationClass::Render(float rotation, float x, float y, float z, float textureTranslation) { XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix; + float positionX, positionY, positionZ, radius; XMFLOAT4 diffuseColor[4], lightPosition[4]; - int i; - bool result; + int modelCount, renderCount, i; + bool result, renderModel; // Clear the buffers to begin the scene. m_Direct3D->BeginScene(0.0f, 0.0f, 0.0f, 1.0f); // Generate the view matrix based on the camera's position. + m_Camera->SetPosition(0.0f, 0.0f, -10.0f); m_Camera->Render(); // Get the world, view, and projection matrices from the camera and d3d objects. @@ -546,14 +777,123 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) m_Direct3D->GetProjectionMatrix(projectionMatrix); m_Direct3D->GetOrthoMatrix(orthoMatrix); + // Setup matrices - Top display plane. + worldMatrix = XMMatrixTranslation(0.0f, 1.5f, 0.0f); + + // Render the display plane using the texture shader and the render texture resource. + m_DisplayPlane->Render(m_Direct3D->GetDeviceContext()); + + result = m_TranslateShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, + m_Model->GetTexture(0), textureTranslation); + if (!result) + { + return false; + } + + // Setup matrices - Bottom left display plane. + worldMatrix = XMMatrixTranslation(-1.5f, -1.5f, 0.0f); + + // Render the display plane using the texture shader and the render texture resource. + m_DisplayPlane->Render(m_Direct3D->GetDeviceContext()); + + result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_DisplayPlane->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_RenderTexture->GetShaderResourceView()); + if (!result) + { + return false; + } + + // Setup matrices - Bottom right display plane. + worldMatrix = XMMatrixTranslation(1.5f, -1.5f, 0.0f); + + // Render the display plane using the texture shader and the render texture resource. + m_DisplayPlane->Render(m_Direct3D->GetDeviceContext()); + + result = m_TextureShader->Render(m_Direct3D->GetDeviceContext(), m_DisplayPlane->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_RenderTexture->GetShaderResourceView()); + if (!result) + { + return false; + } + + // Get the light properties. + for (i = 0; i < m_numLights; i++) + { + // Create the diffuse color array from the four light colors. + diffuseColor[i] = m_Lights[i].GetDiffuseColor(); + + // Create the light position array from the four light positions. + lightPosition[i] = m_Lights[i].GetPosition(); + } + + // Construct the frustum. + m_Frustum->ConstructFrustum(viewMatrix, projectionMatrix, SCREEN_DEPTH); + + // Get the number of models that will be rendered. + modelCount = m_ModelList->GetModelCount(); + + // Initialize the count of models that have been rendered. + renderCount = 0; + + // Go through all the models and render them only if they can be seen by the camera view. + for (i = 0; i < modelCount; i++) + { + // Get the position and color of the sphere model at this index. + m_ModelList->GetData(i, positionX, positionY, positionZ); + + // Set the radius of the sphere to 1.0 since this is already known. + radius = 1.0f; + + // Check if the sphere model is in the view frustum. + renderModel = m_Frustum->CheckSphere(positionX, positionY, positionZ, radius); + + // If it can be seen then render it, if not skip this model and check the next sphere. + if (renderModel) + { + // Move the model to the location it should be rendered at. + worldMatrix = XMMatrixTranslation(positionX, positionY, positionZ); + + // Render the model using the light shader. + m_Model->Render(m_Direct3D->GetDeviceContext()); + + result = m_LightShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, + m_Model->GetTexture(0), diffuseColor, lightPosition); + if (!result) + { + return false; + } + + // Since this model was rendered then increase the count for this frame. + renderCount++; + } + } + + // Update the render count text. + result = UpdateRenderCountString(renderCount); + if (!result) + { + return false; + } + // Disable the Z buffer and enable alpha blending for 2D rendering. m_Direct3D->TurnZBufferOff(); m_Direct3D->EnableAlphaBlending(); + // Reset the world matrix. + m_Direct3D->GetWorldMatrix(worldMatrix); + + // Render the render count text string using the font shader. + m_RenderCountString->Render(m_Direct3D->GetDeviceContext()); + + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_RenderCountString->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix, + m_Font->GetTexture(), m_RenderCountString->GetPixelColor()); + if (!result) + { + return false; + } + // Render the fps text string using the font shader. m_FpsString->Render(m_Direct3D->GetDeviceContext()); - result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_FpsString->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_FpsString->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix, m_Font->GetTexture(), m_FpsString->GetPixelColor()); if (!result) { @@ -563,7 +903,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) // Render the first text string using the font shader. m_TextString1->Render(m_Direct3D->GetDeviceContext()); - result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString1->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString1->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix, m_Font->GetTexture(), m_TextString1->GetPixelColor()); if (!result) { @@ -573,7 +913,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) // Render the second text string using the font shader. m_TextString2->Render(m_Direct3D->GetDeviceContext()); - result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString2->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString2->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix, m_Font->GetTexture(), m_TextString2->GetPixelColor()); if (!result) { @@ -583,7 +923,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) // Render the second text string using the font shader. m_TextString3->Render(m_Direct3D->GetDeviceContext()); - result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString3->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_TextString3->GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix, m_Font->GetTexture(), m_TextString3->GetPixelColor()); if (!result) { @@ -595,7 +935,7 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) { m_MouseStrings[i].Render(m_Direct3D->GetDeviceContext()); - result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_MouseStrings[i].GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix, + result = m_FontShader->Render(m_Direct3D->GetDeviceContext(), m_MouseStrings[i].GetIndexCount(), worldMatrix, m_baseViewMatrix, orthoMatrix, m_Font->GetTexture(), m_MouseStrings[i].GetPixelColor()); if (!result) { @@ -643,16 +983,16 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) // lightPosition[i] = m_Lights[i].GetPosition(); //} - scaleMatrix = XMMatrixScaling(0.75f, 0.75f, 0.75f); // Build the scaling matrix. - rotateMatrix = XMMatrixRotationY(rotation); // Build the rotation matrix. - translateMatrix = XMMatrixTranslation(x, y, z); // Build the translation matrix. + //scaleMatrix = XMMatrixScaling(0.75f, 0.75f, 0.75f); // Build the scaling matrix. + //rotateMatrix = XMMatrixRotationY(rotation); // Build the rotation matrix. + //translateMatrix = XMMatrixTranslation(x, y, z); // Build the translation matrix. - // Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix. - srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); - worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); + //// Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix. + //srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); + //worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); - // Render the model using the multitexture shader. - m_Model->Render(m_Direct3D->GetDeviceContext()); + //// Render the model using the multitexture shader. + //m_Model->Render(m_Direct3D->GetDeviceContext()); result = m_ShaderManager->RenderTextureShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0)); @@ -723,6 +1063,26 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) return false; }*/ + ////Specular Mapping + //result = m_SpecMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, + // m_Model->GetTexture(0), m_Model->GetTexture(1), m_Model->GetTexture(2), m_Light->GetDirection(), m_Light->GetDiffuseColor(), + // m_Camera->GetPosition(), m_Light->GetSpecularColor(), m_Light->GetSpecularPower()); + //if (!result) + //{ + // return false; + //} + + //scaleMatrix = XMMatrixScaling(1.0f, 1.0f, 1.0f); // Build the scaling matrix. + //rotateMatrix = XMMatrixRotationY(40); // Build the rotation matrix. + //translateMatrix = XMMatrixTranslation(0, -2.0f, -10.0f); // Build the translation matrix. + + //// Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix. + //srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); + //worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); + + //// Render the model using the multitexture shader. + //m_Model->Render(m_Direct3D->GetDeviceContext()); + ////Normal Mapping //result = m_NormalMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, // m_Model->GetTexture(0), m_Model->GetTexture(1), m_Light->GetDirection(), m_Light->GetDiffuseColor()); @@ -731,14 +1091,24 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z) // return false; //} - //Specular Mapping - /*result = m_SpecMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, - m_Model->GetTexture(0), m_Model->GetTexture(1), m_Model->GetTexture(2), m_Light->GetDirection(), m_Light->GetDiffuseColor(), - m_Camera->GetPosition(), m_Light->GetSpecularColor(), m_Light->GetSpecularPower()); - if (!result) - { - return false; - }*/ + //scaleMatrix = XMMatrixScaling(1.0f, 1.0f, 1.0f); // Build the scaling matrix. + //rotateMatrix = XMMatrixRotationY(40); // Build the rotation matrix. + //translateMatrix = XMMatrixTranslation(0, 5.0f, -10.0f); // Build the translation matrix. + + //// Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix. + //srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix); + //worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix); + + //// Render the model using the multitexture shader. + //m_Model->Render(m_Direct3D->GetDeviceContext()); + + ////Normal Mapping + //result = m_NormalMapShader->Render(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, + // m_Model->GetTexture(0), m_Model->GetTexture(1), m_Light->GetDirection(), m_Light->GetDiffuseColor()); + //if (!result) + //{ + // return false; + //} // Enable the Z buffer and disable alpha blending now that 2D rendering is complete. m_Direct3D->TurnZBufferOn(); @@ -764,7 +1134,7 @@ bool ApplicationClass::UpdateMouseStrings(int mouseX, int mouseY, bool mouseDown strcat_s(finalString, tempString); // Update the sentence vertex buffer with the new string information. - result = m_MouseStrings[0].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 10, 1.0f, 1.0f, 1.0f); + result = m_MouseStrings[0].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 50, 1.0f, 1.0f, 1.0f); if (!result) { return false; @@ -778,7 +1148,7 @@ bool ApplicationClass::UpdateMouseStrings(int mouseX, int mouseY, bool mouseDown strcat_s(finalString, tempString); // Update the sentence vertex buffer with the new string information. - result = m_MouseStrings[1].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 35, 1.0f, 1.0f, 1.0f); + result = m_MouseStrings[1].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 75, 1.0f, 1.0f, 1.0f); if (!result) { return false; @@ -795,7 +1165,7 @@ bool ApplicationClass::UpdateMouseStrings(int mouseX, int mouseY, bool mouseDown } // Update the sentence vertex buffer with the new string information. - result = m_MouseStrings[2].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 60, 1.0f, 1.0f, 1.0f); + result = m_MouseStrings[2].UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 100, 1.0f, 1.0f, 1.0f); } bool ApplicationClass::UpdateFps() @@ -865,5 +1235,28 @@ bool ApplicationClass::UpdateFps() return false; } + return true; +} + +bool ApplicationClass::UpdateRenderCountString(int renderCount) +{ + char tempString[16], finalString[32]; + bool result; + + + // Convert the render count integer to string format. + sprintf_s(tempString, "%d", renderCount); + + // Setup the render count string. + strcpy_s(finalString, "Render Count: "); + strcat_s(finalString, tempString); + + // Update the sentence vertex buffer with the new string information. + result = m_RenderCountString->UpdateText(m_Direct3D->GetDeviceContext(), m_Font, finalString, 10, 30, 1.0f, 1.0f, 1.0f); + if (!result) + { + return false; + } + return true; } \ No newline at end of file diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index ffcac3c..f8f11a3 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -22,6 +22,12 @@ #include "fpsclass.h" #include "inputclass.h" #include "shadermanagerclass.h" +#include "modellistclass.h" +#include "positionclass.h" +#include "frustumclass.h" +#include "rendertextureclass.h" +#include "displayplaneclass.h" +#include "translateshaderclass.h" ///////////// @@ -48,9 +54,11 @@ public: bool Frame(InputClass*); private: - bool Render(float, float, float, float); + bool Render(float, float, float, float, float); bool UpdateMouseStrings(int, int, bool); bool UpdateFps(); + bool UpdateRenderCountString(int); + bool RenderSceneToTexture(float); private: D3DClass* m_Direct3D; @@ -68,12 +76,21 @@ private: TextClass* m_MouseStrings; int m_numLights; FontShaderClass* m_FontShader; + TextClass* m_RenderCountString; FontClass* m_Font; TextClass *m_TextString1, *m_TextString2, *m_TextString3; FpsClass* m_Fps; TextClass* m_FpsString; int m_previousFps; ShaderManagerClass* m_ShaderManager; + ModelListClass* m_ModelList; + PositionClass* m_Position; + FrustumClass* m_Frustum; + XMMATRIX m_baseViewMatrix; + RenderTextureClass* m_RenderTexture; + DisplayPlaneClass* m_DisplayPlane; + float m_screenWidth, m_screenHeight; + TranslateShaderClass* m_TranslateShader; }; #endif diff --git a/enginecustom/displayplaneclass.cpp b/enginecustom/displayplaneclass.cpp new file mode 100644 index 0000000..798489b --- /dev/null +++ b/enginecustom/displayplaneclass.cpp @@ -0,0 +1,199 @@ +#include "displayplaneclass.h" + + +DisplayPlaneClass::DisplayPlaneClass() +{ + m_vertexBuffer = 0; + m_indexBuffer = 0; +} + + +DisplayPlaneClass::DisplayPlaneClass(const DisplayPlaneClass& other) +{ +} + + +DisplayPlaneClass::~DisplayPlaneClass() +{ +} + +bool DisplayPlaneClass::Initialize(ID3D11Device* device, float width, float height) +{ + bool result; + + + // Initialize the vertex and index buffer that hold the geometry for the button. + result = InitializeBuffers(device, width, height); + if (!result) + { + return false; + } + + return true; +} + + +void DisplayPlaneClass::Shutdown() +{ + // Release the vertex and index buffers. + ShutdownBuffers(); + + return; +} + + +void DisplayPlaneClass::Render(ID3D11DeviceContext* deviceContext) +{ + // Put the vertex and index buffers on the graphics pipeline to prepare them for drawing. + RenderBuffers(deviceContext); + + return; +} + + +int DisplayPlaneClass::GetIndexCount() +{ + return m_indexCount; +} + +bool DisplayPlaneClass::InitializeBuffers(ID3D11Device* device, float width, float height) +{ + VertexType* vertices; + unsigned long* indices; + D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; + D3D11_SUBRESOURCE_DATA vertexData, indexData; + HRESULT result; + int i; + + + // Set the number of vertices in the vertex array. + m_vertexCount = 6; + + // Set the number of indices in the index array. + m_indexCount = m_vertexCount; + + // Create the vertex array. + vertices = new VertexType[m_vertexCount]; + + // Create the index array. + indices = new unsigned long[m_indexCount]; + + // Load the vertex array with data. + // First triangle. + vertices[0].position = XMFLOAT3(-width, height, 0.0f); // Top left. + vertices[0].texture = XMFLOAT2(0.0f, 0.0f); + + vertices[1].position = XMFLOAT3(width, -height, 0.0f); // Bottom right. + vertices[1].texture = XMFLOAT2(1.0f, 1.0f); + + vertices[2].position = XMFLOAT3(-width, -height, 0.0f); // Bottom left. + vertices[2].texture = XMFLOAT2(0.0f, 1.0f); + + // Second triangle. + vertices[3].position = XMFLOAT3(-width, height, 0.0f); // Top left. + vertices[3].texture = XMFLOAT2(0.0f, 0.0f); + + vertices[4].position = XMFLOAT3(width, height, 0.0f); // Top right. + vertices[4].texture = XMFLOAT2(1.0f, 0.0f); + + vertices[5].position = XMFLOAT3(width, -height, 0.0f); // Bottom right. + vertices[5].texture = XMFLOAT2(1.0f, 1.0f); + + // Load the index array with data. + for (i = 0; i < m_indexCount; i++) + { + indices[i] = i; + } + + // Set up the description of the vertex buffer. + vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; + vertexBufferDesc.ByteWidth = sizeof(VertexType) * m_vertexCount; + vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vertexBufferDesc.CPUAccessFlags = 0; + vertexBufferDesc.MiscFlags = 0; + vertexBufferDesc.StructureByteStride = 0; + + // Give the subresource structure a pointer to the vertex data. + vertexData.pSysMem = vertices; + vertexData.SysMemPitch = 0; + vertexData.SysMemSlicePitch = 0; + + // Now finally create the vertex buffer. + result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer); + if (FAILED(result)) + { + return false; + } + + // Set up the description of the index buffer. + indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; + indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_indexCount; + indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + indexBufferDesc.CPUAccessFlags = 0; + indexBufferDesc.MiscFlags = 0; + indexBufferDesc.StructureByteStride = 0; + + // Give the subresource structure a pointer to the index data. + indexData.pSysMem = indices; + indexData.SysMemPitch = 0; + indexData.SysMemSlicePitch = 0; + + // Create the index buffer. + result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer); + if (FAILED(result)) + { + return false; + } + + // Release the arrays now that the vertex and index buffers have been created and loaded. + delete[] vertices; + vertices = 0; + + delete[] indices; + indices = 0; + + return true; +} + + +void DisplayPlaneClass::ShutdownBuffers() +{ + // Release the index buffer. + if (m_indexBuffer) + { + m_indexBuffer->Release(); + m_indexBuffer = 0; + } + + // Release the vertex buffer. + if (m_vertexBuffer) + { + m_vertexBuffer->Release(); + m_vertexBuffer = 0; + } + + return; +} + + +void DisplayPlaneClass::RenderBuffers(ID3D11DeviceContext* deviceContext) +{ + unsigned int stride; + unsigned int offset; + + + // Set vertex buffer stride and offset. + stride = sizeof(VertexType); + offset = 0; + + // Set the vertex buffer to active in the input assembler so it can be rendered. + deviceContext->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset); + + // Set the index buffer to active in the input assembler so it can be rendered. + deviceContext->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0); + + // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles. + deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + return; +} \ No newline at end of file diff --git a/enginecustom/displayplaneclass.h b/enginecustom/displayplaneclass.h new file mode 100644 index 0000000..7d91023 --- /dev/null +++ b/enginecustom/displayplaneclass.h @@ -0,0 +1,44 @@ +#ifndef _DISPLAYPLANECLASS_H_ +#define _DISPLAYPLANECLASS_H_ + + +/////////////////////// +// MY CLASS INCLUDES // +/////////////////////// +#include "d3dclass.h" + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: DisplayPlaneClass +//////////////////////////////////////////////////////////////////////////////// +class DisplayPlaneClass +{ +private: + struct VertexType + { + XMFLOAT3 position; + XMFLOAT2 texture; + }; + +public: + DisplayPlaneClass(); + DisplayPlaneClass(const DisplayPlaneClass&); + ~DisplayPlaneClass(); + + bool Initialize(ID3D11Device*, float, float); + void Shutdown(); + void Render(ID3D11DeviceContext*); + + int GetIndexCount(); + +private: + bool InitializeBuffers(ID3D11Device*, float, float); + void ShutdownBuffers(); + void RenderBuffers(ID3D11DeviceContext*); + +private: + ID3D11Buffer* m_vertexBuffer, * m_indexBuffer; + int m_vertexCount, m_indexCount; +}; + +#endif diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index 99273a3..e520d7a 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -1,6 +1,5 @@ - Debug @@ -26,18 +25,23 @@ + + + + + @@ -45,6 +49,7 @@ + @@ -53,17 +58,22 @@ + + + + + @@ -71,6 +81,7 @@ + @@ -85,7 +96,6 @@ - @@ -97,7 +107,6 @@ Pixel Pixel Pixel - false Document @@ -105,7 +114,6 @@ Vertex Vertex Vertex - false Document @@ -127,11 +135,20 @@ + + + Designer + Document + + + Designer + Document + + 17.0 Win32Proj {92cf56c4-76bb-40d4-8fe5-36c15f5f127a} - enginecustom 10.0 @@ -236,14 +253,4 @@ - - - - - - Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}. - - - - \ No newline at end of file diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index 4b67cfa..ad0862c 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -100,6 +100,22 @@ Fichiers sources + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + + Fichiers sources + + Fichiers sources @@ -174,6 +190,22 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + + Fichiers d%27en-tête + + Fichiers d%27en-tête @@ -280,4 +312,12 @@ assets + + + shader + + + shader + + \ No newline at end of file diff --git a/enginecustom/frustumclass.cpp b/enginecustom/frustumclass.cpp new file mode 100644 index 0000000..7f3f2ab --- /dev/null +++ b/enginecustom/frustumclass.cpp @@ -0,0 +1,296 @@ +#include "frustumclass.h" + + +FrustumClass::FrustumClass() +{ +} + + +FrustumClass::FrustumClass(const FrustumClass& other) +{ +} + + +FrustumClass::~FrustumClass() +{ +} + +void FrustumClass::ConstructFrustum(XMMATRIX viewMatrix, XMMATRIX projectionMatrix, float screenDepth) +{ + XMMATRIX finalMatrix; + XMFLOAT4X4 projMatrix, matrix; + float zMinimum, r, t; + + // Load the projection matrix into a XMFLOAT4X4 structure. + XMStoreFloat4x4(&projMatrix, projectionMatrix); + + // Calculate the minimum Z distance in the frustum. + zMinimum = -projMatrix._43 / projMatrix._33; + r = screenDepth / (screenDepth - zMinimum); + projMatrix._33 = r; + projMatrix._43 = -r * zMinimum; + + // Load the updated XMFLOAT4X4 back into the original projection matrix. + projectionMatrix = XMLoadFloat4x4(&projMatrix); + + // Create the frustum matrix from the view matrix and updated projection matrix. + finalMatrix = XMMatrixMultiply(viewMatrix, projectionMatrix); + + // Load the final matrix into a XMFLOAT4X4 structure. + XMStoreFloat4x4(&matrix, finalMatrix); + + // Get the near plane of the frustum. + m_planes[0].x = matrix._13; + m_planes[0].y = matrix._23; + m_planes[0].z = matrix._33; + m_planes[0].w = matrix._43; + + // Normalize it. + t = (float)sqrt((m_planes[0].x * m_planes[0].x) + (m_planes[0].y * m_planes[0].y) + (m_planes[0].z * m_planes[0].z)); + m_planes[0].x /= t; + m_planes[0].y /= t; + m_planes[0].z /= t; + m_planes[0].w /= t; + + // Calculate the far plane of frustum. + m_planes[1].x = matrix._14 - matrix._13; + m_planes[1].y = matrix._24 - matrix._23; + m_planes[1].z = matrix._34 - matrix._33; + m_planes[1].w = matrix._44 - matrix._43; + + // Normalize it. + t = (float)sqrt((m_planes[1].x * m_planes[1].x) + (m_planes[1].y * m_planes[1].y) + (m_planes[1].z * m_planes[1].z)); + m_planes[1].x /= t; + m_planes[1].y /= t; + m_planes[1].z /= t; + m_planes[1].w /= t; + + // Calculate the left plane of frustum. + m_planes[2].x = matrix._14 + matrix._11; + m_planes[2].y = matrix._24 + matrix._21; + m_planes[2].z = matrix._34 + matrix._31; + m_planes[2].w = matrix._44 + matrix._41; + + // Normalize it. + t = (float)sqrt((m_planes[2].x * m_planes[2].x) + (m_planes[2].y * m_planes[2].y) + (m_planes[2].z * m_planes[2].z)); + m_planes[2].x /= t; + m_planes[2].y /= t; + m_planes[2].z /= t; + m_planes[2].w /= t; + + // Calculate the right plane of frustum. + m_planes[3].x = matrix._14 - matrix._11; + m_planes[3].y = matrix._24 - matrix._21; + m_planes[3].z = matrix._34 - matrix._31; + m_planes[3].w = matrix._44 - matrix._41; + + // Normalize it. + t = (float)sqrt((m_planes[3].x * m_planes[3].x) + (m_planes[3].y * m_planes[3].y) + (m_planes[3].z * m_planes[3].z)); + m_planes[3].x /= t; + m_planes[3].y /= t; + m_planes[3].z /= t; + m_planes[3].w /= t; + + // Calculate the top plane of frustum. + m_planes[4].x = matrix._14 - matrix._12; + m_planes[4].y = matrix._24 - matrix._22; + m_planes[4].z = matrix._34 - matrix._32; + m_planes[4].w = matrix._44 - matrix._42; + + // Normalize it. + t = (float)sqrt((m_planes[4].x * m_planes[4].x) + (m_planes[4].y * m_planes[4].y) + (m_planes[4].z * m_planes[4].z)); + m_planes[4].x /= t; + m_planes[4].y /= t; + m_planes[4].z /= t; + m_planes[4].w /= t; + + // Calculate the bottom plane of frustum. + m_planes[5].x = matrix._14 + matrix._12; + m_planes[5].y = matrix._24 + matrix._22; + m_planes[5].z = matrix._34 + matrix._32; + m_planes[5].w = matrix._44 + matrix._42; + + // Normalize it. + t = (float)sqrt((m_planes[5].x * m_planes[5].x) + (m_planes[5].y * m_planes[5].y) + (m_planes[5].z * m_planes[5].z)); + m_planes[5].x /= t; + m_planes[5].y /= t; + m_planes[5].z /= t; + m_planes[5].w /= t; + + return; +} + +bool FrustumClass::CheckPoint(float x, float y, float z) +{ + int i; + + + // Check if the point is inside all six planes of the view frustum. + for (i = 0; i < 6; i++) + { + if (((m_planes[i].x * x) + (m_planes[i].y * y) + (m_planes[i].z * z) + m_planes[i].w) < 0.0f) + { + return false; + } + } + + return true; +} + +bool FrustumClass::CheckCube(float xCenter, float yCenter, float zCenter, float radius) +{ + int i; + + + // Check if any one point of the cube is in the view frustum. + for (i = 0; i < 6; i++) + { + if (m_planes[i].x * (xCenter - radius) + + m_planes[i].y * (yCenter - radius) + + m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + radius) + + m_planes[i].y * (yCenter - radius) + + m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter - radius) + + m_planes[i].y * (yCenter + radius) + + m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + radius) + + m_planes[i].y * (yCenter + radius) + + m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter - radius) + + m_planes[i].y * (yCenter - radius) + + m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + radius) + + m_planes[i].y * (yCenter - radius) + + m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter - radius) + + m_planes[i].y * (yCenter + radius) + + m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + radius) + + m_planes[i].y * (yCenter + radius) + + m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f) + { + continue; + } + + return false; + } + + return true; +} + +bool FrustumClass::CheckSphere(float xCenter, float yCenter, float zCenter, float radius) +{ + int i; + + + // Check if the radius of the sphere is inside the view frustum. + for (i = 0; i < 6; i++) + { + if (((m_planes[i].x * xCenter) + (m_planes[i].y * yCenter) + (m_planes[i].z * zCenter) + m_planes[i].w) < -radius) + { + return false; + } + } + + return true; +} + +bool FrustumClass::CheckRectangle(float xCenter, float yCenter, float zCenter, float xSize, float ySize, float zSize) +{ + int i; + + + // Check if any of the 6 planes of the rectangle are inside the view frustum. + for (i = 0; i < 6; i++) + { + if (m_planes[i].x * (xCenter - xSize) + + m_planes[i].y * (yCenter - ySize) + + m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + xSize) + + m_planes[i].y * (yCenter - ySize) + + m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter - xSize) + + m_planes[i].y * (yCenter + ySize) + + m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter - xSize) + + m_planes[i].y * (yCenter - ySize) + + m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + xSize) + + m_planes[i].y * (yCenter + ySize) + + m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + xSize) + + m_planes[i].y * (yCenter - ySize) + + m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter - xSize) + + m_planes[i].y * (yCenter + ySize) + + m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + if (m_planes[i].x * (xCenter + xSize) + + m_planes[i].y * (yCenter + ySize) + + m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f) + { + continue; + } + + return false; + } + + return true; +} + diff --git a/enginecustom/frustumclass.h b/enginecustom/frustumclass.h new file mode 100644 index 0000000..6d3e3d0 --- /dev/null +++ b/enginecustom/frustumclass.h @@ -0,0 +1,33 @@ +#ifndef _FRUSTUMCLASS_H_ +#define _FRUSTUMCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +using namespace DirectX; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: FrustumClass +//////////////////////////////////////////////////////////////////////////////// +class FrustumClass +{ +public: + FrustumClass(); + FrustumClass(const FrustumClass&); + ~FrustumClass(); + + void ConstructFrustum(XMMATRIX, XMMATRIX, float); + + bool CheckPoint(float, float, float); + bool CheckCube(float, float, float, float); + bool CheckSphere(float, float, float, float); + bool CheckRectangle(float, float, float, float, float, float); + +private: + XMFLOAT4 m_planes[6]; +}; + +#endif \ No newline at end of file diff --git a/enginecustom/inputclass.cpp b/enginecustom/inputclass.cpp index c50216a..2a2c91f 100644 --- a/enginecustom/inputclass.cpp +++ b/enginecustom/inputclass.cpp @@ -234,11 +234,11 @@ void InputClass::ProcessInput() m_mouseX += m_mouseState.lX; m_mouseY += m_mouseState.lY; - // Ensure the mouse location doesn't exceed the screen width or height. - if (m_mouseX < 0) { m_mouseX = 0; } - if (m_mouseY < 0) { m_mouseY = 0; } + //// Ensure the mouse location doesn't exceed the screen width or height. + //if (m_mouseX < 0) { m_mouseX = 0; } + if (m_mouseY < -m_screenHeight) { m_mouseY = -m_screenHeight; } - if (m_mouseX > m_screenWidth) { m_mouseX = m_screenWidth; } + //if (m_mouseX > m_screenWidth) { m_mouseX = m_screenWidth; } if (m_mouseY > m_screenHeight) { m_mouseY = m_screenHeight; } return; @@ -255,6 +255,94 @@ bool InputClass::IsEscapePressed() return false; } +bool InputClass::IsLeftArrowPressed() +{ + if (m_keyboardState[DIK_LEFT] & 0x80) + { + return true; + } + + return false; +} + + +bool InputClass::IsRightArrowPressed() +{ + if (m_keyboardState[DIK_RIGHT] & 0x80) + { + return true; + } + + return false; +} + +/////////////////////////////////////////////////// +// Les touches correspondent aux claviers QWERTY // +/////////////////////////////////////////////////// + +bool InputClass::IsAPressed() +{ + // Touche A sur QWERTY, Q sur AZERTY + if (m_keyboardState[DIK_A] & 0x80) + { + return true; + } + + return false; +} + +bool InputClass::IsDPressed() +{ + if (m_keyboardState[DIK_D] & 0x80) + { + return true; + } + + return false; +} + +bool InputClass::IsWPressed() +{ + // Touche W sur QWERTY, Z sur AZERTY + if (m_keyboardState[DIK_W] & 0x80) + { + return true; + } + + return false; +} + +bool InputClass::IsSPressed() +{ + if (m_keyboardState[DIK_S] & 0x80) + { + return true; + } + + return false; +} + +bool InputClass::IsQPressed() +{ + // Touche Q sur QWERTY, A sur AZERTY + if (m_keyboardState[DIK_Q] & 0x80) + { + return true; + } + + return false; +} + +bool InputClass::IsEPressed() +{ + if (m_keyboardState[DIK_E] & 0x80) + { + return true; + } + + return false; +} + void InputClass::GetMouseLocation(int& mouseX, int& mouseY) { mouseX = m_mouseX; diff --git a/enginecustom/inputclass.h b/enginecustom/inputclass.h index 21d3c2b..d559872 100644 --- a/enginecustom/inputclass.h +++ b/enginecustom/inputclass.h @@ -36,6 +36,14 @@ public: bool IsMousePressed(); void KeyDown(unsigned int); void KeyUp(unsigned int); + bool IsLeftArrowPressed(); + bool IsRightArrowPressed(); + bool IsAPressed(); + bool IsDPressed(); + bool IsWPressed(); + bool IsSPressed(); + bool IsQPressed(); + bool IsEPressed(); bool IsKeyDown(unsigned int); diff --git a/enginecustom/packages.config b/enginecustom/packages.config deleted file mode 100644 index cbf6205..0000000 --- a/enginecustom/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/enginecustom/rendertextureclass.cpp b/enginecustom/rendertextureclass.cpp new file mode 100644 index 0000000..d4435a8 --- /dev/null +++ b/enginecustom/rendertextureclass.cpp @@ -0,0 +1,248 @@ +#include "rendertextureclass.h" + +RenderTextureClass::RenderTextureClass() +{ + m_renderTargetTexture = 0; + m_renderTargetView = 0; + m_shaderResourceView = 0; + m_depthStencilBuffer = 0; + m_depthStencilView = 0; +} + + +RenderTextureClass::RenderTextureClass(const RenderTextureClass& other) +{ +} + + +RenderTextureClass::~RenderTextureClass() +{ +} + +bool RenderTextureClass::Initialize(ID3D11Device * device, int textureWidth, int textureHeight, float screenDepth, float screenNear, int format) +{ + D3D11_TEXTURE2D_DESC textureDesc; + HRESULT result; + D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; + D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; + D3D11_TEXTURE2D_DESC depthBufferDesc; + D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; + DXGI_FORMAT textureFormat; + + + // Set the texture format. + switch (format) + { + case 1: + { + textureFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + } + default: + { + textureFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + } + } + + // Store the width and height of the render texture. + m_textureWidth = textureWidth; + m_textureHeight = textureHeight; + + // Initialize the render target texture description. + ZeroMemory(&textureDesc, sizeof(textureDesc)); + + // Setup the render target texture description. + textureDesc.Width = textureWidth; + textureDesc.Height = textureHeight; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = textureFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + + // Create the render target texture. + result = device->CreateTexture2D(&textureDesc, NULL, &m_renderTargetTexture); + if (FAILED(result)) + { + return false; + } + + // Setup the description of the render target view. + renderTargetViewDesc.Format = textureDesc.Format; + renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + renderTargetViewDesc.Texture2D.MipSlice = 0; + + // Create the render target view. + result = device->CreateRenderTargetView(m_renderTargetTexture, &renderTargetViewDesc, &m_renderTargetView); + if (FAILED(result)) + { + return false; + } + + // Setup the description of the shader resource view. + shaderResourceViewDesc.Format = textureDesc.Format; + shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; + shaderResourceViewDesc.Texture2D.MipLevels = 1; + + // Create the shader resource view. + result = device->CreateShaderResourceView(m_renderTargetTexture, &shaderResourceViewDesc, &m_shaderResourceView); + if (FAILED(result)) + { + return false; + } + + // Initialize the description of the depth buffer. + ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); + + // Set up the description of the depth buffer. + depthBufferDesc.Width = textureWidth; + depthBufferDesc.Height = textureHeight; + depthBufferDesc.MipLevels = 1; + depthBufferDesc.ArraySize = 1; + depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthBufferDesc.SampleDesc.Count = 1; + depthBufferDesc.SampleDesc.Quality = 0; + depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; + depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + depthBufferDesc.CPUAccessFlags = 0; + depthBufferDesc.MiscFlags = 0; + + // Create the texture for the depth buffer using the filled out description. + result = device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); + if (FAILED(result)) + { + return false; + } + + // Initailze the depth stencil view description. + ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); + + // Set up the depth stencil view description. + depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + depthStencilViewDesc.Texture2D.MipSlice = 0; + + // Create the depth stencil view. + result = device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); + if (FAILED(result)) + { + return false; + } + + // Setup the viewport for rendering. + m_viewport.Width = (float)textureWidth; + m_viewport.Height = (float)textureHeight; + m_viewport.MinDepth = 0.0f; + m_viewport.MaxDepth = 1.0f; + m_viewport.TopLeftX = 0; + m_viewport.TopLeftY = 0; + + // Setup the projection matrix. + m_projectionMatrix = XMMatrixPerspectiveFovLH((3.141592654f / 4.0f), ((float)textureWidth / (float)textureHeight), screenNear, screenDepth); + + // Create an orthographic projection matrix for 2D rendering. + m_orthoMatrix = XMMatrixOrthographicLH((float)textureWidth, (float)textureHeight, screenNear, screenDepth); + + return true; +} + +void RenderTextureClass::Shutdown() +{ + if (m_depthStencilView) + { + m_depthStencilView->Release(); + m_depthStencilView = 0; + } + + if (m_depthStencilBuffer) + { + m_depthStencilBuffer->Release(); + m_depthStencilBuffer = 0; + } + + if (m_shaderResourceView) + { + m_shaderResourceView->Release(); + m_shaderResourceView = 0; + } + + if (m_renderTargetView) + { + m_renderTargetView->Release(); + m_renderTargetView = 0; + } + + if (m_renderTargetTexture) + { + m_renderTargetTexture->Release(); + m_renderTargetTexture = 0; + } + + return; +} + +void RenderTextureClass::SetRenderTarget(ID3D11DeviceContext * deviceContext) +{ + // Bind the render target view and depth stencil buffer to the output render pipeline. + deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); + + // Set the viewport. + deviceContext->RSSetViewports(1, &m_viewport); + + return; +} + +void RenderTextureClass::ClearRenderTarget(ID3D11DeviceContext * deviceContext, float red, float green, float blue, float alpha) +{ + float color[4]; + + + // Setup the color to clear the buffer to. + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = alpha; + + // Clear the back buffer. + deviceContext->ClearRenderTargetView(m_renderTargetView, color); + + // Clear the depth buffer. + deviceContext->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); + + return; +} + +ID3D11ShaderResourceView* RenderTextureClass::GetShaderResourceView() +{ + return m_shaderResourceView; +} + +void RenderTextureClass::GetProjectionMatrix(XMMATRIX & projectionMatrix) +{ + projectionMatrix = m_projectionMatrix; + return; +} + + +void RenderTextureClass::GetOrthoMatrix(XMMATRIX & orthoMatrix) +{ + orthoMatrix = m_orthoMatrix; + return; +} + + +int RenderTextureClass::GetTextureWidth() +{ + return m_textureWidth; +} + + +int RenderTextureClass::GetTextureHeight() +{ + return m_textureHeight; +} \ No newline at end of file diff --git a/enginecustom/rendertextureclass.h b/enginecustom/rendertextureclass.h new file mode 100644 index 0000000..ef06537 --- /dev/null +++ b/enginecustom/rendertextureclass.h @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////// +// Filename: rendertextureclass.h +//////////////////////////////////////////////////////////////////////////////// +#ifndef _RENDERTEXTURECLASS_H_ +#define _RENDERTEXTURECLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +using namespace DirectX; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: RenderTextureClass +//////////////////////////////////////////////////////////////////////////////// +class RenderTextureClass +{ +public: + RenderTextureClass(); + RenderTextureClass(const RenderTextureClass&); + ~RenderTextureClass(); + + bool Initialize(ID3D11Device*, int, int, float, float, int); + void Shutdown(); + + void SetRenderTarget(ID3D11DeviceContext*); + void ClearRenderTarget(ID3D11DeviceContext*, float, float, float, float); + ID3D11ShaderResourceView* GetShaderResourceView(); + + void GetProjectionMatrix(XMMATRIX&); + void GetOrthoMatrix(XMMATRIX&); + + int GetTextureWidth(); + int GetTextureHeight(); + +private: + int m_textureWidth, m_textureHeight; + ID3D11Texture2D* m_renderTargetTexture; + ID3D11RenderTargetView* m_renderTargetView; + ID3D11ShaderResourceView* m_shaderResourceView; + ID3D11Texture2D* m_depthStencilBuffer; + ID3D11DepthStencilView* m_depthStencilView; + D3D11_VIEWPORT m_viewport; + XMMATRIX m_projectionMatrix; + XMMATRIX m_orthoMatrix; +}; + +#endif diff --git a/enginecustom/translate.ps b/enginecustom/translate.ps new file mode 100644 index 0000000..51a964b --- /dev/null +++ b/enginecustom/translate.ps @@ -0,0 +1,37 @@ +///////////// +// GLOBALS // +///////////// +Texture2D shaderTexture : register(t0); +SamplerState SampleType : register(s0); + +cbuffer TranslationBuffer +{ + float textureTranslation; +}; + + +////////////// +// TYPEDEFS // +////////////// +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Pixel Shader +//////////////////////////////////////////////////////////////////////////////// +float4 TranslatePixelShader(PixelInputType input) : SV_TARGET +{ + float4 textureColor; + + + // Translate the position where we sample the pixel from. + input.tex.x += textureTranslation; + + // Sample the pixel color from the texture using the sampler at this texture coordinate location. + textureColor = shaderTexture.Sample(SampleType, input.tex); + + return textureColor; +} diff --git a/enginecustom/translate.vs b/enginecustom/translate.vs new file mode 100644 index 0000000..847ced0 --- /dev/null +++ b/enginecustom/translate.vs @@ -0,0 +1,48 @@ +///////////// +// GLOBALS // +///////////// +cbuffer MatrixBuffer +{ + matrix worldMatrix; + matrix viewMatrix; + matrix projectionMatrix; +}; + + +////////////// +// TYPEDEFS // +////////////// +struct VertexInputType +{ + float4 position : POSITION; + float2 tex : TEXCOORD0; +}; + +struct PixelInputType +{ + float4 position : SV_POSITION; + float2 tex : TEXCOORD0; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Vertex Shader +//////////////////////////////////////////////////////////////////////////////// +PixelInputType TranslateVertexShader(VertexInputType input) +{ + PixelInputType output; + + + // Change the position vector to be 4 units for proper matrix calculations. + input.position.w = 1.0f; + + // Calculate the position of the vertex against the world, view, and projection matrices. + output.position = mul(input.position, worldMatrix); + output.position = mul(output.position, viewMatrix); + output.position = mul(output.position, projectionMatrix); + + // Store the texture coordinates for the pixel shader. + output.tex = input.tex; + + return output; +} diff --git a/enginecustom/translateshaderclass.cpp b/enginecustom/translateshaderclass.cpp new file mode 100644 index 0000000..8be41d1 --- /dev/null +++ b/enginecustom/translateshaderclass.cpp @@ -0,0 +1,416 @@ +#include "translateshaderclass.h" + + +TranslateShaderClass::TranslateShaderClass() +{ + m_vertexShader = 0; + m_pixelShader = 0; + m_layout = 0; + m_matrixBuffer = 0; + m_sampleState = 0; + + m_translateBuffer = 0; +} + + +TranslateShaderClass::TranslateShaderClass(const TranslateShaderClass& other) +{ +} + + +TranslateShaderClass::~TranslateShaderClass() +{ +} + + +bool TranslateShaderClass::Initialize(ID3D11Device* device, HWND hwnd) +{ + bool result; + wchar_t vsFilename[128]; + wchar_t psFilename[128]; + int error; + + // Set the filename of the vertex shader. + error = wcscpy_s(vsFilename, 128, L"translate.vs"); + if (error != 0) + { + return false; + } + + // Set the filename of the pixel shader. + error = wcscpy_s(psFilename, 128, L"translate.ps"); + if (error != 0) + { + return false; + } + + // Initialize the vertex and pixel shaders. + result = InitializeShader(device, hwnd, vsFilename, psFilename); + if (!result) + { + return false; + } + + return true; +} + + +void TranslateShaderClass::Shutdown() +{ + // Shutdown the vertex and pixel shaders as well as the related objects. + ShutdownShader(); + + return; +} + +bool TranslateShaderClass::Render(ID3D11DeviceContext * deviceContext, int indexCount, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView * texture, float translation) +{ + bool result; + + + // Set the shader parameters that it will use for rendering. + result = SetShaderParameters(deviceContext, worldMatrix, viewMatrix, projectionMatrix, texture, translation); + if (!result) + { + return false; + } + + // Now render the prepared buffers with the shader. + RenderShader(deviceContext, indexCount); + + return true; +} + + +bool TranslateShaderClass::InitializeShader(ID3D11Device * device, HWND hwnd, WCHAR * vsFilename, WCHAR * psFilename) +{ + HRESULT result; + ID3D10Blob* errorMessage; + ID3D10Blob* vertexShaderBuffer; + ID3D10Blob* pixelShaderBuffer; + D3D11_INPUT_ELEMENT_DESC polygonLayout[2]; + unsigned int numElements; + D3D11_BUFFER_DESC matrixBufferDesc; + D3D11_SAMPLER_DESC samplerDesc; + D3D11_BUFFER_DESC translateBufferDesc; + + + // Initialize the pointers this function will use to null. + errorMessage = 0; + vertexShaderBuffer = 0; + pixelShaderBuffer = 0; + + // Compile the vertex shader code. + result = D3DCompileFromFile(vsFilename, NULL, NULL, "TranslateVertexShader", "vs_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, + &vertexShaderBuffer, &errorMessage); + if (FAILED(result)) + { + // If the shader failed to compile it should have writen something to the error message. + if (errorMessage) + { + OutputShaderErrorMessage(errorMessage, hwnd, vsFilename); + } + // If there was nothing in the error message then it simply could not find the shader file itself. + else + { + MessageBox(hwnd, vsFilename, L"Missing Shader File", MB_OK); + } + + return false; + } + + // Compile the pixel shader code. + result = D3DCompileFromFile(psFilename, NULL, NULL, "TranslatePixelShader", "ps_5_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, + &pixelShaderBuffer, &errorMessage); + if (FAILED(result)) + { + // If the shader failed to compile it should have writen something to the error message. + if (errorMessage) + { + OutputShaderErrorMessage(errorMessage, hwnd, psFilename); + } + // If there was nothing in the error message then it simply could not find the file itself. + else + { + MessageBox(hwnd, psFilename, L"Missing Shader File", MB_OK); + } + + return false; + } + + // Create the vertex shader from the buffer. + result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader); + if (FAILED(result)) + { + return false; + } + + // Create the pixel shader from the buffer. + result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader); + if (FAILED(result)) + { + return false; + } + + // Create the vertex input layout description. + polygonLayout[0].SemanticName = "POSITION"; + polygonLayout[0].SemanticIndex = 0; + polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; + polygonLayout[0].InputSlot = 0; + polygonLayout[0].AlignedByteOffset = 0; + polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[0].InstanceDataStepRate = 0; + + polygonLayout[1].SemanticName = "TEXCOORD"; + polygonLayout[1].SemanticIndex = 0; + polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT; + polygonLayout[1].InputSlot = 0; + polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; + polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + polygonLayout[1].InstanceDataStepRate = 0; + + // Get a count of the elements in the layout. + numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]); + + // Create the vertex input layout. + result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), + vertexShaderBuffer->GetBufferSize(), &m_layout); + if (FAILED(result)) + { + return false; + } + + // Release the vertex shader buffer and pixel shader buffer since they are no longer needed. + vertexShaderBuffer->Release(); + vertexShaderBuffer = 0; + + pixelShaderBuffer->Release(); + pixelShaderBuffer = 0; + + // Setup the description of the dynamic matrix constant buffer that is in the vertex shader. + matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + matrixBufferDesc.ByteWidth = sizeof(MatrixBufferType); + matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + matrixBufferDesc.MiscFlags = 0; + matrixBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class. + result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer); + if (FAILED(result)) + { + return false; + } + + // Create a texture sampler state description. + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + samplerDesc.BorderColor[0] = 0; + samplerDesc.BorderColor[1] = 0; + samplerDesc.BorderColor[2] = 0; + samplerDesc.BorderColor[3] = 0; + samplerDesc.MinLOD = 0; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + + // Create the texture sampler state. + result = device->CreateSamplerState(&samplerDesc, &m_sampleState); + if (FAILED(result)) + { + return false; + } + + // Setup the description of the texture translation dynamic constant buffer that is in the pixel shader. + translateBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + translateBufferDesc.ByteWidth = sizeof(TranslateBufferType); + translateBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + translateBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + translateBufferDesc.MiscFlags = 0; + translateBufferDesc.StructureByteStride = 0; + + // Create the constant buffer pointer so we can access the pixel shader constant buffer from within this class. + result = device->CreateBuffer(&translateBufferDesc, NULL, &m_translateBuffer); + if (FAILED(result)) + { + return false; + } + + return true; +} + + +void TranslateShaderClass::ShutdownShader() +{ + + // Release the texture translation constant buffer. + if (m_translateBuffer) + { + m_translateBuffer->Release(); + m_translateBuffer = 0; + } + + // Release the sampler state. + if (m_sampleState) + { + m_sampleState->Release(); + m_sampleState = 0; + } + + // Release the matrix constant buffer. + if (m_matrixBuffer) + { + m_matrixBuffer->Release(); + m_matrixBuffer = 0; + } + + // Release the layout. + if (m_layout) + { + m_layout->Release(); + m_layout = 0; + } + + // Release the pixel shader. + if (m_pixelShader) + { + m_pixelShader->Release(); + m_pixelShader = 0; + } + + // Release the vertex shader. + if (m_vertexShader) + { + m_vertexShader->Release(); + m_vertexShader = 0; + } + + return; +} + + +void TranslateShaderClass::OutputShaderErrorMessage(ID3D10Blob * errorMessage, HWND hwnd, WCHAR * shaderFilename) +{ + char* compileErrors; + unsigned long long bufferSize, i; + ofstream fout; + + + // Get a pointer to the error message text buffer. + compileErrors = (char*)(errorMessage->GetBufferPointer()); + + // Get the length of the message. + bufferSize = errorMessage->GetBufferSize(); + + // Open a file to write the error message to. + fout.open("shader-error.txt"); + + // Write out the error message. + for (i = 0; i < bufferSize; i++) + { + fout << compileErrors[i]; + } + + // Close the file. + fout.close(); + + // Release the error message. + errorMessage->Release(); + errorMessage = 0; + + // Pop a message up on the screen to notify the user to check the text file for compile errors. + MessageBox(hwnd, L"Error compiling shader. Check shader-error.txt for message.", shaderFilename, MB_OK); + + return; +} + + +bool TranslateShaderClass::SetShaderParameters(ID3D11DeviceContext * deviceContext, XMMATRIX worldMatrix, XMMATRIX viewMatrix, + XMMATRIX projectionMatrix, ID3D11ShaderResourceView * texture, float translation) +{ + HRESULT result; + D3D11_MAPPED_SUBRESOURCE mappedResource; + MatrixBufferType* dataPtr; + unsigned int bufferNumber; + TranslateBufferType* dataPtr2; + + + // Transpose the matrices to prepare them for the shader. + worldMatrix = XMMatrixTranspose(worldMatrix); + viewMatrix = XMMatrixTranspose(viewMatrix); + projectionMatrix = XMMatrixTranspose(projectionMatrix); + + // Lock the constant buffer so it can be written to. + result = deviceContext->Map(m_matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the constant buffer. + dataPtr = (MatrixBufferType*)mappedResource.pData; + + // Copy the matrices into the constant buffer. + dataPtr->world = worldMatrix; + dataPtr->view = viewMatrix; + dataPtr->projection = projectionMatrix; + + // Unlock the constant buffer. + deviceContext->Unmap(m_matrixBuffer, 0); + + // Set the position of the constant buffer in the vertex shader. + bufferNumber = 0; + + // Finally set the constant buffer in the vertex shader with the updated values. + deviceContext->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer); + + // Set shader texture resource in the pixel shader. + deviceContext->PSSetShaderResources(0, 1, &texture); + + // Lock the texture translation constant buffer so it can be written to. + result = deviceContext->Map(m_translateBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return false; + } + + // Get a pointer to the data in the texture translation constant buffer. + dataPtr2 = (TranslateBufferType*)mappedResource.pData; + + // Copy the translation value into the texture translation constant buffer. + dataPtr2->translation = translation; + + // Unlock the buffer. + deviceContext->Unmap(m_translateBuffer, 0); + + // Set the position of the texture translation constant buffer in the pixel shader. + bufferNumber = 0; + + // Now set the texture translation constant buffer in the pixel shader with the updated values. + deviceContext->PSSetConstantBuffers(bufferNumber, 1, &m_translateBuffer); + + return true; +} + + +void TranslateShaderClass::RenderShader(ID3D11DeviceContext * deviceContext, int indexCount) +{ + // Set the vertex input layout. + deviceContext->IASetInputLayout(m_layout); + + // Set the vertex and pixel shaders that will be used to render this triangle. + deviceContext->VSSetShader(m_vertexShader, NULL, 0); + deviceContext->PSSetShader(m_pixelShader, NULL, 0); + + // Set the sampler state in the pixel shader. + deviceContext->PSSetSamplers(0, 1, &m_sampleState); + + // Render the geometry. + deviceContext->DrawIndexed(indexCount, 0, 0); + + return; +} \ No newline at end of file diff --git a/enginecustom/translateshaderclass.h b/enginecustom/translateshaderclass.h new file mode 100644 index 0000000..a51f1ab --- /dev/null +++ b/enginecustom/translateshaderclass.h @@ -0,0 +1,62 @@ +#ifndef _TRANSLATESHADERCLASS_H_ +#define _TRANSLATESHADERCLASS_H_ + + +////////////// +// INCLUDES // +////////////// +#include +#include +#include +#include +using namespace DirectX; +using namespace std; + + +//////////////////////////////////////////////////////////////////////////////// +// Class name: TranslateShaderClass +//////////////////////////////////////////////////////////////////////////////// +class TranslateShaderClass +{ +private: + struct MatrixBufferType + { + XMMATRIX world; + XMMATRIX view; + XMMATRIX projection; + }; + + struct TranslateBufferType + { + float translation; + XMFLOAT3 padding; + }; + +public: + TranslateShaderClass(); + TranslateShaderClass(const TranslateShaderClass&); + ~TranslateShaderClass(); + + bool Initialize(ID3D11Device*, HWND); + void Shutdown(); + bool Render(ID3D11DeviceContext*, int, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, float); + +private: + bool InitializeShader(ID3D11Device*, HWND, WCHAR*, WCHAR*); + void ShutdownShader(); + void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*); + + bool SetShaderParameters(ID3D11DeviceContext*, XMMATRIX, XMMATRIX, XMMATRIX, ID3D11ShaderResourceView*, float); + void RenderShader(ID3D11DeviceContext*, int); + +private: + ID3D11VertexShader* m_vertexShader; + ID3D11PixelShader* m_pixelShader; + ID3D11InputLayout* m_layout; + ID3D11Buffer* m_matrixBuffer; + ID3D11SamplerState* m_sampleState; + + ID3D11Buffer* m_translateBuffer; +}; + +#endif