2020-05-27 09:21:20 +02:00
|
|
|
#include "framework.h"
|
2020-01-08 20:57:33 +01:00
|
|
|
#include "Renderer11.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "configuration.h"
|
|
|
|
#include "savegame.h"
|
|
|
|
#include "health.h"
|
|
|
|
#include "camera.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "inventory.h"
|
|
|
|
#include "lara.h"
|
|
|
|
#include "gameflow.h"
|
|
|
|
#include "rope.h"
|
|
|
|
#include "tomb4fx.h"
|
|
|
|
#include "door.h"
|
|
|
|
#include "level.h"
|
|
|
|
#include "setup.h"
|
|
|
|
#include "control.h"
|
|
|
|
#include "sound.h"
|
2020-05-27 19:07:34 +02:00
|
|
|
#include "tr5_rats_emitter.h"
|
|
|
|
#include "tr5_bats_emitter.h"
|
|
|
|
#include "tr5_spider_emitter.h"
|
2020-06-21 20:57:35 +02:00
|
|
|
#include "ConstantBuffers/CameraMatrixBuffer.h"
|
2020-08-02 19:39:55 +02:00
|
|
|
#include <Objects\TR4\Entity\tr4_wraith.h>
|
2020-08-06 06:51:32 +02:00
|
|
|
#include <Objects\TR4\Entity\tr4_littlebeetle.h>
|
2020-07-01 08:46:07 +02:00
|
|
|
#include "RenderView/RenderView.h"
|
2020-07-25 21:03:02 +02:00
|
|
|
#include "hair.h"
|
2020-07-03 10:09:13 +02:00
|
|
|
extern T5M::Renderer::RendererHUDBar *g_DashBar;
|
|
|
|
extern T5M::Renderer::RendererHUDBar *g_SFXVolumeBar;
|
|
|
|
extern T5M::Renderer::RendererHUDBar *g_MusicVolumeBar;
|
2020-01-08 20:57:33 +01:00
|
|
|
extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
namespace T5M::Renderer
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
using namespace T5M::Renderer;
|
|
|
|
using namespace std::chrono;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawPickup(short objectNum)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
drawObjectOn2DPosition(700 + PickupX, 450, objectNum, 0, m_pickupRotation, 0); // TODO: + PickupY
|
|
|
|
m_pickupRotation += 45 * 360 / 30;
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Matrix translation;
|
|
|
|
Matrix rotation;
|
|
|
|
Matrix world;
|
|
|
|
Matrix view;
|
|
|
|
Matrix projection;
|
|
|
|
Matrix scale;
|
|
|
|
|
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
x *= (ScreenWidth / 800.0f);
|
|
|
|
y *= (ScreenHeight / 600.0f);
|
|
|
|
|
|
|
|
view = Matrix::CreateLookAt(Vector3(0.0f, 0.0f, 2048.0f), Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, -1.0f, 0.0f));
|
|
|
|
projection = Matrix::CreateOrthographic(ScreenWidth, ScreenHeight, -1024.0f, 1024.0f);
|
|
|
|
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO *obj = &Objects[objectNum];
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &moveableObj = *m_moveableObjects[objectNum];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (obj->animIndex != -1)
|
|
|
|
{
|
2020-07-26 08:58:44 +02:00
|
|
|
ANIM_FRAME *frame[] = {&g_Level.Frames[g_Level.Anims[obj->animIndex].framePtr]};
|
2020-07-25 18:02:35 +02:00
|
|
|
updateAnimation(NULL, moveableObj, frame, 0, 0, 0xFFFFFFFF);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Vector3 pos = m_viewportToolkit->Unproject(Vector3(x, y, 1), projection, view, Matrix::Identity);
|
|
|
|
|
|
|
|
// Clear just the Z-buffer so we can start drawing on top of the scene
|
2020-07-26 08:58:44 +02:00
|
|
|
ID3D11DepthStencilView *dsv;
|
|
|
|
m_context->OMGetRenderTargets(1, NULL, &dsv);
|
2020-07-23 21:38:12 +02:00
|
|
|
m_context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set vertex buffer
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
|
|
|
// Set shaders
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsInventory.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psInventory.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set texture
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
m_context->PSSetShaderResources(2, 1, (std::get<1>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicClamp();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
|
|
|
// Set matrices
|
2020-07-01 08:46:07 +02:00
|
|
|
CCameraMatrixBuffer HudCamera;
|
|
|
|
HudCamera.ViewProjection = view * projection;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbCameraMatrices.updateData(HudCamera, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int n = 0; n < moveableObj.ObjectMeshes.size(); n++)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = moveableObj.ObjectMeshes[n];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Finish the world matrix
|
|
|
|
translation = Matrix::CreateTranslation(pos.x, pos.y, pos.z + 1024.0f);
|
|
|
|
rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(rotY), TO_RAD(rotX), TO_RAD(rotZ));
|
|
|
|
scale = Matrix::CreateScale(0.5f);
|
|
|
|
|
|
|
|
world = scale * rotation;
|
|
|
|
world = world * translation;
|
|
|
|
|
|
|
|
if (obj->animIndex != -1)
|
2020-06-28 11:12:52 +02:00
|
|
|
m_stItem.World = (moveableObj.AnimationTransforms[n] * world);
|
2020-06-27 19:48:50 +02:00
|
|
|
else
|
2020-06-28 11:12:52 +02:00
|
|
|
m_stItem.World = (moveableObj.BindPoseTransforms[n] * world);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_stItem.AmbientLight = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int m = 0; m < NUM_BUCKETS; m++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[m];
|
2020-07-05 06:20:36 +02:00
|
|
|
if (bucket->Vertices.size() == 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (m < 2)
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
else
|
|
|
|
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
|
|
|
|
|
|
|
|
m_stMisc.AlphaTest = (m < 2);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderShadowMap(RenderView& renderView)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_shadowLight = NULL;
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererLight *brightestLight = NULL;
|
2020-06-27 19:48:50 +02:00
|
|
|
float brightest = 0.0f;
|
|
|
|
Vector3 itemPosition = Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
|
|
|
|
2020-07-25 21:03:02 +02:00
|
|
|
for (int k = 0; k < renderView.roomsToDraw.size(); k++)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-07-25 21:03:02 +02:00
|
|
|
RendererRoom *room = renderView.roomsToDraw[k];
|
2020-06-27 19:48:50 +02:00
|
|
|
int numLights = room->Lights.size();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = 0; j < numLights; j++)
|
|
|
|
{
|
|
|
|
RendererLight *light = &room->Lights[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Check only lights different from sun
|
2020-07-03 10:09:13 +02:00
|
|
|
if (light->Type == LIGHT_TYPE_SUN)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Sun is added without checks
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else if (light->Type == LIGHT_TYPE_POINT)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Vector3 lightPosition = Vector3(light->Position.x, light->Position.y, light->Position.z);
|
|
|
|
|
|
|
|
float distance = (itemPosition - lightPosition).Length();
|
|
|
|
|
|
|
|
// Collect only lights nearer than 20 sectors
|
|
|
|
if (distance >= 20 * WALL_SIZE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Check the out radius
|
|
|
|
if (distance > light->Out)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
float attenuation = 1.0f - distance / light->Out;
|
|
|
|
float intensity = max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (intensity >= brightest)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
brightest = intensity;
|
|
|
|
brightestLight = light;
|
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else if (light->Type == LIGHT_TYPE_SPOT)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Vector3 lightPosition = Vector3(light->Position.x, light->Position.y, light->Position.z);
|
|
|
|
|
|
|
|
float distance = (itemPosition - lightPosition).Length();
|
|
|
|
|
|
|
|
// Collect only lights nearer than 20 sectors
|
|
|
|
if (distance >= 20 * WALL_SIZE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Check the range
|
|
|
|
if (distance > light->Range)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// If Lara, try to collect shadow casting light
|
|
|
|
float attenuation = 1.0f - distance / light->Range;
|
|
|
|
float intensity = max(0.0f, attenuation * (light->Color.x + light->Color.y + light->Color.z) / 3.0f);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (intensity >= brightest)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
brightest = intensity;
|
|
|
|
brightestLight = light;
|
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Invalid light type
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_shadowLight = brightestLight;
|
|
|
|
|
|
|
|
if (m_shadowLight == NULL)
|
2020-08-09 15:25:56 +02:00
|
|
|
return;
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Reset GPU state
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
|
|
|
|
// Bind and clear render target
|
|
|
|
m_context->ClearRenderTargetView(m_shadowMap.RenderTargetView.Get(), Colors::White);
|
|
|
|
m_context->ClearDepthStencilView(m_shadowMap.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
|
|
|
m_context->OMSetRenderTargets(1, m_shadowMap.RenderTargetView.GetAddressOf(), m_shadowMap.DepthStencilView.Get());
|
|
|
|
|
|
|
|
m_context->RSSetViewports(1, &m_shadowMapViewport);
|
|
|
|
|
|
|
|
//drawLara(false, true);
|
|
|
|
|
|
|
|
Vector3 lightPos = Vector3(m_shadowLight->Position.x, m_shadowLight->Position.y, m_shadowLight->Position.z);
|
|
|
|
Vector3 itemPos = Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
|
|
|
if (lightPos == itemPos)
|
2020-08-09 15:25:56 +02:00
|
|
|
return;
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
// Set shaders
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsShadowMap.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psShadowMap.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
|
|
|
// Set texture
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
m_context->PSSetShaderResources(2, 1, (std::get<1>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicClamp();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
|
|
|
// Set camera matrices
|
|
|
|
Matrix view = Matrix::CreateLookAt(lightPos,
|
|
|
|
itemPos,
|
|
|
|
Vector3(0.0f, -1.0f, 0.0f));
|
|
|
|
Matrix projection = Matrix::CreatePerspectiveFieldOfView(90.0f * RADIAN, 1.0f, 64.0f,
|
|
|
|
(m_shadowLight->Type == LIGHT_TYPE_POINT ? m_shadowLight->Out : m_shadowLight->Range) * 1.2f);
|
2020-07-01 08:46:07 +02:00
|
|
|
CCameraMatrixBuffer shadowProjection;
|
|
|
|
shadowProjection.ViewProjection = view * projection;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbCameraMatrices.updateData(shadowProjection, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stShadowMap.LightViewProjection = (view * projection);
|
|
|
|
|
|
|
|
m_stMisc.AlphaTest = true;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &laraObj = *m_moveableObjects[ID_LARA];
|
|
|
|
RendererObject &laraSkin = *m_moveableObjects[ID_LARA_SKIN];
|
|
|
|
RendererRoom &const room = m_rooms[LaraItem->roomNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stItem.World = m_LaraWorldMatrix;
|
|
|
|
m_stItem.Position = Vector4(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, 1.0f);
|
|
|
|
m_stItem.AmbientLight = room.AmbientLight;
|
2020-06-28 11:12:52 +02:00
|
|
|
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * 32);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = getMesh(Lara.meshPtrs[k]);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = 0; j < 2; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Draw vertices
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (m_moveableObjects[ID_LARA_SKIN_JOINTS].has_value())
|
|
|
|
{
|
|
|
|
RendererObject &laraSkinJoints = *m_moveableObjects[ID_LARA_SKIN_JOINTS];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < laraSkinJoints.ObjectMeshes.size(); k++)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = laraSkinJoints.ObjectMeshes[k];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = 0; j < 2; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Draw vertices
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = laraSkin.ObjectMeshes[k];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = 0; j < NUM_BUCKETS; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Draw vertices
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw items
|
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
RendererObject &hairsObj = *m_moveableObjects[ID_LARA_HAIR];
|
|
|
|
|
|
|
|
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
|
2020-06-27 19:48:50 +02:00
|
|
|
m_stItem.World = Matrix::Identity;
|
2020-07-26 08:58:44 +02:00
|
|
|
Matrix matrices[7];
|
|
|
|
matrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
|
|
|
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
|
|
|
|
{
|
|
|
|
HAIR_STRUCT *hairs = &Hairs[0][i];
|
|
|
|
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.yRot), TO_RAD(hairs->pos.xRot), 0) * Matrix::CreateTranslation(hairs->pos.xPos, hairs->pos.yPos, hairs->pos.zPos);
|
|
|
|
matrices[i + 1] = world;
|
|
|
|
}
|
|
|
|
memcpy(m_stItem.BonesMatrices, matrices, sizeof(Matrix) * 7);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-07-26 08:58:44 +02:00
|
|
|
RendererMesh *mesh = hairsObj.ObjectMeshes[k];
|
|
|
|
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Draw vertices
|
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderTitleImage()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
wchar_t introFileChars[255];
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
std::mbstowcs(introFileChars, g_GameFlow->Intro, 255);
|
2020-06-27 19:48:50 +02:00
|
|
|
std::wstring titleStringFileName(introFileChars);
|
2020-08-09 22:15:32 +02:00
|
|
|
Texture2D texture = Texture2D(m_device.Get(), titleStringFileName);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
float currentFade = 0;
|
2020-07-03 10:09:13 +02:00
|
|
|
while (currentFade <= 1.0f)
|
|
|
|
{
|
|
|
|
drawFullScreenImage(texture.ShaderResourceView.Get(), currentFade, m_backBufferRTV, m_depthStencilView);
|
2020-06-27 19:48:50 +02:00
|
|
|
SyncRenderer();
|
|
|
|
currentFade += FADE_FACTOR;
|
2020-06-30 10:25:41 +02:00
|
|
|
m_swapChain->Present(0, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < 30 * 1.5f; i++)
|
|
|
|
{
|
|
|
|
drawFullScreenImage(texture.ShaderResourceView.Get(), 1.0f, m_backBufferRTV, m_depthStencilView);
|
2020-06-27 19:48:50 +02:00
|
|
|
SyncRenderer();
|
2020-06-30 10:25:41 +02:00
|
|
|
m_swapChain->Present(0, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
currentFade = 1.0f;
|
2020-07-03 10:09:13 +02:00
|
|
|
while (currentFade >= 0.0f)
|
|
|
|
{
|
|
|
|
drawFullScreenImage(texture.ShaderResourceView.Get(), currentFade, m_backBufferRTV, m_depthStencilView);
|
2020-06-27 19:48:50 +02:00
|
|
|
SyncRenderer();
|
|
|
|
currentFade -= FADE_FACTOR;
|
2020-06-30 10:25:41 +02:00
|
|
|
m_swapChain->Present(0, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawGunShells()
|
|
|
|
{
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererRoom &const room = m_rooms[LaraItem->roomNumber];
|
|
|
|
RendererItem *item = &m_items[Lara.itemNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stItem.AmbientLight = room.AmbientLight;
|
|
|
|
memcpy(m_stItem.BonesMatrices, &Matrix::Identity, sizeof(Matrix));
|
|
|
|
|
|
|
|
m_stLights.NumLights = item->Lights.size();
|
|
|
|
for (int j = 0; j < item->Lights.size(); j++)
|
|
|
|
memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight));
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbLights.updateData(m_stLights, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stMisc.AlphaTest = true;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < 24; i++)
|
|
|
|
{
|
|
|
|
GUNSHELL_STRUCT *gunshell = &Gunshells[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (gunshell->counter > 0)
|
|
|
|
{
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO *obj = &Objects[gunshell->objectNumber];
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &moveableObj = *m_moveableObjects[gunshell->objectNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
Matrix translation = Matrix::CreateTranslation(gunshell->pos.xPos, gunshell->pos.yPos, gunshell->pos.zPos);
|
|
|
|
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(gunshell->pos.yRot), TO_RAD(gunshell->pos.xRot), TO_RAD(gunshell->pos.zRot));
|
|
|
|
Matrix world = rotation * translation;
|
|
|
|
|
|
|
|
m_stItem.World = world;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererMesh *mesh = moveableObj.ObjectMeshes[0];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int b = 0; b < NUM_BUCKETS; b++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[b];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-05 06:20:36 +02:00
|
|
|
if (bucket->Vertices.size() == 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
|
|
|
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderInventoryScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, ID3D11ShaderResourceView* background)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
char stringBuffer[255];
|
|
|
|
|
|
|
|
bool drawLogo = true;
|
|
|
|
|
|
|
|
RECT guiRect;
|
|
|
|
Vector4 guiColor = Vector4(0.0f, 0.0f, 0.25f, 0.5f);
|
|
|
|
bool drawGuiRect = false;
|
|
|
|
|
|
|
|
RECT rect;
|
|
|
|
rect.left = 0;
|
|
|
|
rect.top = 0;
|
|
|
|
rect.right = ScreenWidth;
|
|
|
|
rect.bottom = ScreenHeight;
|
|
|
|
|
|
|
|
m_lines2DToDraw.clear();
|
|
|
|
m_strings.clear();
|
|
|
|
|
|
|
|
m_nextLine2D = 0;
|
|
|
|
|
|
|
|
// Set basic render states
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
|
|
|
|
// Bind and clear render target
|
2020-06-30 10:25:41 +02:00
|
|
|
//m_context->ClearRenderTargetView(target, Colors::Black);
|
|
|
|
//m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
|
|
|
m_context->OMSetRenderTargets(1, &target, depthTarget);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->RSSetViewports(1, &m_viewport);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (background != nullptr)
|
|
|
|
{
|
|
|
|
drawFullScreenImage(background, 0.5f, target, depthTarget);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 10:25:41 +02:00
|
|
|
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
// Set vertex buffer
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
|
|
|
// Set shaders
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsInventory.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psInventory.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set texture
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetShaderResources(2, 1, (std::get<1>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
2020-07-18 14:53:26 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicClamp();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
InventoryRing *activeRing = g_Inventory.GetRing(g_Inventory.GetActiveRing());
|
2020-06-27 19:48:50 +02:00
|
|
|
int lastRing = 0;
|
|
|
|
|
|
|
|
float cameraX = INV_CAMERA_DISTANCE * cos(g_Inventory.GetCameraTilt() * RADIAN);
|
|
|
|
float cameraY = g_Inventory.GetCameraY() - INV_CAMERA_DISTANCE * sin(g_Inventory.GetCameraTilt() * RADIAN);
|
|
|
|
float cameraZ = 0.0f;
|
2020-07-01 08:46:07 +02:00
|
|
|
CCameraMatrixBuffer inventoryCam;
|
|
|
|
inventoryCam.ViewProjection = Matrix::CreateLookAt(Vector3(cameraX, cameraY, cameraZ),
|
2020-07-03 10:09:13 +02:00
|
|
|
Vector3(0.0f, g_Inventory.GetCameraY() - 512.0f, 0.0f), Vector3(0.0f, -1.0f, 0.0f)) *
|
|
|
|
Matrix::CreatePerspectiveFieldOfView(80.0f * RADIAN,
|
|
|
|
g_Renderer.ScreenWidth / (float)g_Renderer.ScreenHeight, 1.0f, 200000.0f);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbCameraMatrices.updateData(inventoryCam, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < NUM_INVENTORY_RINGS; k++)
|
|
|
|
{
|
|
|
|
InventoryRing *ring = g_Inventory.GetRing(k);
|
2020-06-27 19:48:50 +02:00
|
|
|
if (ring->draw == false || ring->numObjects == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
short numObjects = ring->numObjects;
|
|
|
|
float deltaAngle = 360.0f / numObjects;
|
|
|
|
int objectIndex = 0;
|
|
|
|
objectIndex = ring->currentObject;
|
|
|
|
|
|
|
|
// Yellow title
|
|
|
|
if (ring->focusState == INV_FOCUS_STATE_NONE && g_Inventory.GetType() != INV_TYPE_TITLE)
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, 20, g_GameFlow->GetString(activeRing->titleStringIndex), PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < numObjects; i++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
short inventoryObject = ring->objects[objectIndex].inventoryObject;
|
|
|
|
short objectNumber = g_Inventory.GetInventoryObject(ring->objects[objectIndex].inventoryObject)->objectNumber;
|
|
|
|
|
|
|
|
//if (ring->focusState != INV_FOCUS_STATE_NONE && (k != g_Inventory->GetActiveRing() || inventoryObject != ring->objects[i].inventoryObject))
|
|
|
|
// continue;
|
|
|
|
|
|
|
|
// Calculate the inventory object position and rotation
|
|
|
|
float currentAngle = 0.0f;
|
|
|
|
short steps = -objectIndex + ring->currentObject;
|
|
|
|
if (steps < 0)
|
|
|
|
steps += numObjects;
|
|
|
|
currentAngle = steps * deltaAngle;
|
|
|
|
currentAngle += ring->rotation;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (ring->focusState == INV_FOCUS_STATE_NONE && k == g_Inventory.GetActiveRing())
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
if (objectIndex == ring->currentObject)
|
|
|
|
ring->objects[objectIndex].rotation += 45 * 360 / 30;
|
|
|
|
else if (ring->objects[objectIndex].rotation != 0)
|
|
|
|
ring->objects[objectIndex].rotation += 45 * 360 / 30;
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else if (ring->focusState != INV_FOCUS_STATE_POPUP && ring->focusState != INV_FOCUS_STATE_POPOVER)
|
2020-06-27 19:48:50 +02:00
|
|
|
g_Inventory.GetRing(k)->objects[objectIndex].rotation = 0;
|
|
|
|
|
|
|
|
if (ring->objects[objectIndex].rotation > 65536.0f)
|
|
|
|
ring->objects[objectIndex].rotation = 0;
|
|
|
|
|
|
|
|
int x = ring->distance * cos(currentAngle * RADIAN);
|
|
|
|
int y = g_Inventory.GetRing(k)->y;
|
|
|
|
int z = ring->distance * sin(currentAngle * RADIAN);
|
|
|
|
|
|
|
|
// Prepare the object transform
|
|
|
|
Matrix scale = Matrix::CreateScale(ring->objects[objectIndex].scale, ring->objects[objectIndex].scale, ring->objects[objectIndex].scale);
|
|
|
|
Matrix translation = Matrix::CreateTranslation(x, y, z);
|
|
|
|
Matrix rotation = Matrix::CreateRotationY(TO_RAD(ring->objects[objectIndex].rotation + 16384 + g_Inventory.GetInventoryObject(inventoryObject)->rotY));
|
|
|
|
Matrix transform = (scale * rotation) * translation;
|
|
|
|
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO *obj = &Objects[objectNumber];
|
2020-07-03 10:09:13 +02:00
|
|
|
if (!m_moveableObjects[objectNumber].has_value())
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &moveableObj = *m_moveableObjects[objectNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Build the object animation matrices
|
|
|
|
if (ring->focusState == INV_FOCUS_STATE_FOCUSED && obj->animIndex != -1 &&
|
2020-07-03 10:09:13 +02:00
|
|
|
objectIndex == ring->currentObject && k == g_Inventory.GetActiveRing())
|
|
|
|
{
|
2020-07-26 08:58:44 +02:00
|
|
|
ANIM_FRAME *framePtr[2];
|
2020-06-27 19:48:50 +02:00
|
|
|
int rate = 0;
|
2020-07-25 18:02:35 +02:00
|
|
|
getFrame(obj->animIndex, ring->framePtr, framePtr, &rate);
|
2020-06-27 19:48:50 +02:00
|
|
|
updateAnimation(NULL, moveableObj, framePtr, 0, 1, 0xFFFFFFFF);
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
if (obj->animIndex != -1)
|
2020-07-26 08:58:44 +02:00
|
|
|
{
|
|
|
|
ANIM_FRAME *framePtr = &g_Level.Frames[g_Level.Anims[obj->animIndex].framePtr];
|
|
|
|
updateAnimation(NULL, moveableObj, &framePtr, 0, 1, 0xFFFFFFFF);
|
|
|
|
}
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int n = 0; n < moveableObj.ObjectMeshes.size(); n++)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = moveableObj.ObjectMeshes[n];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// HACK: revolver and crossbow + lasersight
|
2020-06-28 11:12:52 +02:00
|
|
|
if (moveableObj.Id == ID_REVOLVER_ITEM && !Lara.Weapons[WEAPON_REVOLVER].HasLasersight && n > 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
break;
|
|
|
|
|
2020-06-28 11:12:52 +02:00
|
|
|
if (moveableObj.Id == ID_CROSSBOW_ITEM && !Lara.Weapons[WEAPON_CROSSBOW].HasLasersight && n > 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
// Finish the world matrix
|
|
|
|
if (obj->animIndex != -1)
|
2020-06-28 11:12:52 +02:00
|
|
|
m_stItem.World = (moveableObj.AnimationTransforms[n] * transform);
|
2020-06-27 19:48:50 +02:00
|
|
|
else
|
2020-06-28 11:12:52 +02:00
|
|
|
m_stItem.World = (moveableObj.BindPoseTransforms[n] * transform);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_stItem.AmbientLight = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int m = 0; m < NUM_BUCKETS; m++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[m];
|
2020-07-05 06:20:36 +02:00
|
|
|
if (bucket->Vertices.size() == 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (m < 2)
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
else
|
|
|
|
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
|
|
|
|
|
|
|
|
m_stMisc.AlphaTest = (m < 2);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
short inventoryItem = ring->objects[objectIndex].inventoryObject;
|
|
|
|
|
|
|
|
// Draw special stuff if needed
|
2020-07-03 10:09:13 +02:00
|
|
|
if (objectIndex == ring->currentObject && k == g_Inventory.GetActiveRing())
|
|
|
|
{
|
|
|
|
if (g_Inventory.GetActiveRing() == INV_RING_OPTIONS)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
/* **************** PASSAPORT ************* */
|
2020-07-03 10:09:13 +02:00
|
|
|
if (inventoryItem == INV_OBJECT_PASSPORT && ring->focusState == INV_FOCUS_STATE_FOCUSED)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
/* **************** LOAD AND SAVE MENU ************* */
|
2020-07-03 10:09:13 +02:00
|
|
|
if (ring->passportAction == INV_WHAT_PASSPORT_LOAD_GAME || ring->passportAction == INV_WHAT_PASSPORT_SAVE_GAME)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
y = 44;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int n = 0; n < MAX_SAVEGAMES; n++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
if (!g_NewSavegameInfos[n].Present)
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(45), D3DCOLOR_ARGB(255, 255, 255, 255),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == n ? PRINTSTRING_BLINK : 0));
|
2020-07-03 10:09:13 +02:00
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
sprintf(stringBuffer, "%05d", g_NewSavegameInfos[n].Count);
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, stringBuffer, D3DCOLOR_ARGB(255, 255, 255, 255), PRINTSTRING_OUTLINE | (ring->selectedIndex == n ? PRINTSTRING_BLINK | PRINTSTRING_DONT_UPDATE_BLINK : 0));
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(250, y, (char *)g_NewSavegameInfos[n].LevelName.c_str(), D3DCOLOR_ARGB(255, 255, 255, 255), PRINTSTRING_OUTLINE | (ring->selectedIndex == n ? PRINTSTRING_BLINK | PRINTSTRING_DONT_UPDATE_BLINK : 0));
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
sprintf(stringBuffer, g_GameFlow->GetString(44), g_NewSavegameInfos[n].Days, g_NewSavegameInfos[n].Hours, g_NewSavegameInfos[n].Minutes, g_NewSavegameInfos[n].Seconds);
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(475, y, stringBuffer, D3DCOLOR_ARGB(255, 255, 255, 255),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == n ? PRINTSTRING_BLINK : 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
y += 24;
|
|
|
|
}
|
|
|
|
|
|
|
|
drawLogo = false;
|
|
|
|
|
|
|
|
drawGuiRect = true;
|
|
|
|
guiRect.left = 180;
|
|
|
|
guiRect.right = 440;
|
|
|
|
guiRect.top = 24;
|
|
|
|
guiRect.bottom = y + 20 - 24;
|
|
|
|
|
|
|
|
//drawColoredQuad(180, 24, 440, y + 20 - 24, Vector4(0.0f, 0.0f, 0.25f, 0.5f));
|
|
|
|
}
|
|
|
|
/* **************** SELECT LEVEL ************* */
|
2020-07-03 10:09:13 +02:00
|
|
|
else if (ring->passportAction == INV_WHAT_PASSPORT_SELECT_LEVEL)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
drawLogo = false;
|
|
|
|
|
|
|
|
drawGuiRect = true;
|
|
|
|
guiRect.left = 200;
|
|
|
|
guiRect.right = 400;
|
|
|
|
guiRect.top = 24;
|
|
|
|
guiRect.bottom = 24 * (g_GameFlow->GetNumLevels() - 1) + 40;
|
|
|
|
|
|
|
|
//drawColoredQuad(200, 24, 400, 24 * (g_GameFlow->GetNumLevels() - 1) + 40, Vector4(0.0f, 0.0f, 0.25f, 0.5f));
|
|
|
|
|
|
|
|
short lastY = 50;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int n = 1; n < g_GameFlow->GetNumLevels(); n++)
|
|
|
|
{
|
|
|
|
GameScriptLevel *levelScript = g_GameFlow->GetLevel(n);
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, lastY, g_GameFlow->GetString(levelScript->NameStringIndex), D3DCOLOR_ARGB(255, 255, 255, 255),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == n - 1 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
lastY += 24;
|
|
|
|
}
|
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
char *string = (char *)"";
|
|
|
|
switch (ring->passportAction)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
case INV_WHAT_PASSPORT_NEW_GAME:
|
|
|
|
string = g_GameFlow->GetString(STRING_NEW_GAME);
|
|
|
|
break;
|
|
|
|
case INV_WHAT_PASSPORT_SELECT_LEVEL:
|
|
|
|
string = g_GameFlow->GetString(STRING_SELECT_LEVEL);
|
|
|
|
break;
|
|
|
|
case INV_WHAT_PASSPORT_LOAD_GAME:
|
|
|
|
string = g_GameFlow->GetString(STRING_LOAD_GAME);
|
|
|
|
break;
|
|
|
|
case INV_WHAT_PASSPORT_SAVE_GAME:
|
|
|
|
string = g_GameFlow->GetString(STRING_SAVE_GAME);
|
|
|
|
break;
|
|
|
|
case INV_WHAT_PASSPORT_EXIT_GAME:
|
|
|
|
string = g_GameFlow->GetString(STRING_EXIT_GAME);
|
|
|
|
break;
|
|
|
|
case INV_WHAT_PASSPORT_EXIT_TO_TITLE:
|
|
|
|
string = g_GameFlow->GetString(STRING_EXIT_TO_TITLE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, 550, string, PRINTSTRING_COLOR_ORANGE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
/* **************** GRAPHICS SETTINGS ************* */
|
2020-07-03 10:09:13 +02:00
|
|
|
else if (inventoryItem == INV_OBJECT_SUNGLASSES && ring->focusState == INV_FOCUS_STATE_FOCUSED)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw settings menu
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererVideoAdapter *adapter = &m_adapters[g_Configuration.Adapter];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
int y = 200;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_DISPLAY),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_YELLOW, PRINTSTRING_OUTLINE | PRINTSTRING_CENTER);
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Screen resolution
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_SCREEN_RESOLUTION),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 0 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererDisplayMode *mode = &adapter->DisplayModes[ring->SelectedVideoMode];
|
2020-06-27 19:48:50 +02:00
|
|
|
char buffer[255];
|
|
|
|
ZeroMemory(buffer, 255);
|
|
|
|
sprintf(buffer, "%d x %d (%d Hz)", mode->Width, mode->Height, mode->RefreshRate);
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, buffer, PRINTSTRING_COLOR_WHITE,
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 0 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Windowed mode
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_WINDOWED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 1 ? PRINTSTRING_BLINK : 0));
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(ring->Configuration.Windowed ? STRING_ENABLED : STRING_DISABLED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 1 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Enable dynamic shadows
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_SHADOWS),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 2 ? PRINTSTRING_BLINK : 0));
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(ring->Configuration.EnableShadows ? STRING_ENABLED : STRING_DISABLED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 2 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Enable caustics
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_CAUSTICS),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 3 ? PRINTSTRING_BLINK : 0));
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(ring->Configuration.EnableCaustics ? STRING_ENABLED : STRING_DISABLED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 3 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Enable volumetric fog
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_VOLUMETRIC_FOG),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 4 ? PRINTSTRING_BLINK : 0));
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(ring->Configuration.EnableVolumetricFog ? STRING_ENABLED : STRING_DISABLED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 4 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Apply and cancel
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_APPLY),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == 5 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_CANCEL),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == 6 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
drawLogo = false;
|
|
|
|
|
|
|
|
drawGuiRect = true;
|
|
|
|
guiRect.left = 180;
|
|
|
|
guiRect.right = 440;
|
|
|
|
guiRect.top = 180;
|
|
|
|
guiRect.bottom = y + 20 - 180;
|
|
|
|
|
|
|
|
//drawColoredQuad(180, 180, 440, y + 20 - 180, Vector4(0.0f, 0.0f, 0.25f, 0.5f));
|
|
|
|
}
|
|
|
|
/* **************** AUDIO SETTINGS ************* */
|
2020-07-03 10:09:13 +02:00
|
|
|
else if (inventoryItem == INV_OBJECT_HEADPHONES && ring->focusState == INV_FOCUS_STATE_FOCUSED)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw sound menu
|
|
|
|
|
|
|
|
y = 200;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_SOUND),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_YELLOW, PRINTSTRING_OUTLINE | PRINTSTRING_CENTER);
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Enable sound
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_ENABLE_SOUND),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 0 ? PRINTSTRING_BLINK : 0));
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(ring->Configuration.EnableSound ? STRING_ENABLED : STRING_DISABLED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 0 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Enable sound special effects
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_SPECIAL_SOUND_FX),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_DONT_UPDATE_BLINK | PRINTSTRING_OUTLINE | (ring->selectedIndex == 1 ? PRINTSTRING_BLINK : 0));
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(ring->Configuration.EnableAudioSpecialEffects ? STRING_ENABLED : STRING_DISABLED),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 1 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Music volume
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_MUSIC_VOLUME),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 2 ? PRINTSTRING_BLINK : 0));
|
|
|
|
//DrawBar(400, y + 4, 150, 18, ring->Configuration.MusicVolume, 0x0000FF, 0x0000FF);
|
2020-08-09 15:25:56 +02:00
|
|
|
drawBar(ring->Configuration.MusicVolume / 100.0f, g_MusicVolumeBar);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Sound FX volume
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_SFX_VOLUME),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == 3 ? PRINTSTRING_BLINK : 0));
|
|
|
|
//DrawBar(400, y + 4, 150, 18, ring->Configuration.SfxVolume, 0x0000FF, 0x0000FF);
|
2020-08-09 15:25:56 +02:00
|
|
|
drawBar(ring->Configuration.SfxVolume / 100.0f, g_SFXVolumeBar);
|
2020-06-27 19:48:50 +02:00
|
|
|
y += 25;
|
|
|
|
|
|
|
|
// Apply and cancel
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_APPLY),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == 4 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_CANCEL),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == 5 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
drawLogo = false;
|
|
|
|
|
|
|
|
drawGuiRect = true;
|
|
|
|
guiRect.left = 180;
|
|
|
|
guiRect.right = 440;
|
|
|
|
guiRect.top = 180;
|
|
|
|
guiRect.bottom = y + 20 - 180;
|
|
|
|
|
|
|
|
//drawColoredQuad(180, 180, 440, y + 20 - 180, Vector4(0.0f, 0.0f, 0.25f, 0.5f));
|
|
|
|
}
|
|
|
|
/* **************** CONTROLS SETTINGS ************* */
|
2020-07-03 10:09:13 +02:00
|
|
|
else if (inventoryItem == INV_OBJECT_KEYS && ring->focusState == INV_FOCUS_STATE_FOCUSED)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw sound menu
|
|
|
|
y = 40;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_CONTROLS),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_YELLOW, PRINTSTRING_OUTLINE | PRINTSTRING_CENTER);
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < 18; k++)
|
|
|
|
{
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(200, y, g_GameFlow->GetString(STRING_CONTROLS_MOVE_FORWARD + k),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_OUTLINE | (ring->selectedIndex == k ? PRINTSTRING_BLINK : 0) |
|
2020-07-03 10:09:13 +02:00
|
|
|
(ring->waitingForKey ? PRINTSTRING_DONT_UPDATE_BLINK : 0));
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (ring->waitingForKey && k == ring->selectedIndex)
|
|
|
|
{
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_WAITING_FOR_KEY),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_YELLOW,
|
|
|
|
PRINTSTRING_OUTLINE | PRINTSTRING_BLINK);
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, (char *)g_KeyNames[KeyboardLayout[1][k]],
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_OUTLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Apply and cancel
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_APPLY),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == NUM_CONTROLS + 0 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(STRING_CANCEL),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_ORANGE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == NUM_CONTROLS + 1 ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
|
|
|
|
drawLogo = false;
|
|
|
|
|
|
|
|
drawGuiRect = true;
|
|
|
|
guiRect.left = 180;
|
|
|
|
guiRect.right = 440;
|
|
|
|
guiRect.top = 20;
|
|
|
|
guiRect.bottom = y + 20 - 20;
|
|
|
|
|
|
|
|
//drawColoredQuad(180, 20, 440, y + 20 - 20, Vector4(0.0f, 0.0f, 0.25f, 0.5f));
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw the description below the object
|
2020-07-03 10:09:13 +02:00
|
|
|
char *string = g_GameFlow->GetString(g_Inventory.GetInventoryObject(inventoryItem)->objectName); // (char*)g_NewStrings[g_Inventory->GetInventoryObject(inventoryItem)->objectName].c_str(); // &AllStrings[AllStringsOffsets[g_Inventory->GetInventoryObject(inventoryItem)->objectName]];
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, 550, string, PRINTSTRING_COLOR_ORANGE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
short inventoryItem = g_Inventory.GetRing(k)->objects[objectIndex].inventoryObject;
|
2020-07-03 10:09:13 +02:00
|
|
|
char *string = g_GameFlow->GetString(g_Inventory.GetInventoryObject(inventoryItem)->objectName); // &AllStrings[AllStringsOffsets[InventoryObjectsList[inventoryItem].objectName]];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (/*g_Inventory->IsCurrentObjectWeapon() &&*/ ring->focusState == INV_FOCUS_STATE_FOCUSED)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
y = 100;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int a = 0; a < ring->numActions; a++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
int stringIndex = 0;
|
|
|
|
if (ring->actions[a] == INV_ACTION_USE)
|
|
|
|
stringIndex = STRING_USE;
|
|
|
|
if (ring->actions[a] == INV_ACTION_COMBINE)
|
|
|
|
stringIndex = STRING_COMBINE;
|
|
|
|
if (ring->actions[a] == INV_ACTION_SEPARE)
|
|
|
|
stringIndex = STRING_SEPARE;
|
|
|
|
if (ring->actions[a] == INV_ACTION_SELECT_AMMO)
|
|
|
|
stringIndex = STRING_CHOOSE_AMMO;
|
|
|
|
|
|
|
|
// Apply and cancel
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, y, g_GameFlow->GetString(stringIndex),
|
2020-06-27 19:48:50 +02:00
|
|
|
PRINTSTRING_COLOR_WHITE,
|
|
|
|
PRINTSTRING_CENTER | PRINTSTRING_OUTLINE | (ring->selectedIndex == a ? PRINTSTRING_BLINK : 0));
|
|
|
|
|
|
|
|
y += 25;
|
|
|
|
}
|
|
|
|
|
|
|
|
drawLogo = false;
|
|
|
|
|
|
|
|
drawGuiRect = true;
|
|
|
|
guiRect.left = 300;
|
|
|
|
guiRect.right = 200;
|
|
|
|
guiRect.top = 80;
|
|
|
|
guiRect.bottom = y + 20 - 80;
|
|
|
|
|
|
|
|
//drawColoredQuad(300, 80, 200, y + 20 - 80, Vector4(0.0f, 0.0f, 0.25f, 0.5f));
|
|
|
|
}
|
|
|
|
|
|
|
|
int quantity = -1;
|
2020-07-03 10:09:13 +02:00
|
|
|
switch (objectNumber)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
case ID_BIGMEDI_ITEM:
|
|
|
|
quantity = Lara.NumLargeMedipacks;
|
|
|
|
break;
|
|
|
|
case ID_SMALLMEDI_ITEM:
|
|
|
|
quantity = Lara.NumSmallMedipacks;
|
|
|
|
break;
|
|
|
|
case ID_FLARE_INV_ITEM:
|
|
|
|
quantity = Lara.NumFlares;
|
|
|
|
break;
|
|
|
|
case ID_SHOTGUN_AMMO1_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_SHOTGUN].Ammo[0];
|
|
|
|
if (quantity != -1)
|
|
|
|
quantity /= 6;
|
|
|
|
break;
|
|
|
|
case ID_SHOTGUN_AMMO2_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_SHOTGUN].Ammo[1];
|
|
|
|
if (quantity != -1)
|
|
|
|
quantity /= 6;
|
|
|
|
break;
|
|
|
|
case ID_HK_AMMO_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_HK].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_CROSSBOW_AMMO1_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_CROSSBOW].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_CROSSBOW_AMMO2_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_CROSSBOW].Ammo[1];
|
|
|
|
break;
|
|
|
|
case ID_CROSSBOW_AMMO3_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_CROSSBOW].Ammo[2];
|
|
|
|
break;
|
|
|
|
case ID_REVOLVER_AMMO_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_REVOLVER].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_UZI_AMMO_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_UZI].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_PISTOLS_AMMO_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_PISTOLS].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_GRENADE_AMMO1_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_GRENADE_AMMO2_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[1];
|
|
|
|
break;
|
|
|
|
case ID_GRENADE_AMMO3_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_GRENADE_LAUNCHER].Ammo[2];
|
|
|
|
break;
|
|
|
|
case ID_HARPOON_AMMO_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_HARPOON_GUN].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_ROCKET_LAUNCHER_AMMO_ITEM:
|
|
|
|
quantity = Lara.Weapons[WEAPON_ROCKET_LAUNCHER].Ammo[0];
|
|
|
|
break;
|
|
|
|
case ID_PICKUP_ITEM4:
|
|
|
|
quantity = Savegame.Level.Secrets;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (objectNumber >= ID_PUZZLE_ITEM1 && objectNumber <= ID_PUZZLE_ITEM8)
|
|
|
|
quantity = Lara.Puzzles[objectNumber - ID_PUZZLE_ITEM1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_PUZZLE_ITEM1_COMBO1 && objectNumber <= ID_PUZZLE_ITEM8_COMBO2)
|
|
|
|
quantity = Lara.PuzzlesCombo[objectNumber - ID_PUZZLE_ITEM1_COMBO1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_KEY_ITEM1 && objectNumber <= ID_KEY_ITEM8)
|
|
|
|
quantity = Lara.Keys[objectNumber - ID_KEY_ITEM1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_KEY_ITEM1_COMBO1 && objectNumber <= ID_KEY_ITEM8_COMBO2)
|
|
|
|
quantity = Lara.KeysCombo[objectNumber - ID_KEY_ITEM1_COMBO1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_PICKUP_ITEM1 && objectNumber <= ID_PICKUP_ITEM3)
|
|
|
|
quantity = Lara.Pickups[objectNumber - ID_PICKUP_ITEM1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_PICKUP_ITEM1_COMBO1 && objectNumber <= ID_PICKUP_ITEM3_COMBO2)
|
|
|
|
quantity = Lara.PickupsCombo[objectNumber - ID_PICKUP_ITEM1_COMBO1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_EXAMINE1 && objectNumber <= ID_EXAMINE3)
|
|
|
|
quantity = Lara.Pickups[objectNumber - ID_EXAMINE1];
|
|
|
|
|
|
|
|
else if (objectNumber >= ID_EXAMINE1_COMBO1 && objectNumber <= ID_EXAMINE3_COMBO2)
|
|
|
|
quantity = Lara.PickupsCombo[objectNumber - ID_EXAMINE1_COMBO1];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (quantity < 1)
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, 550, string, D3DCOLOR_ARGB(255, 216, 117, 49), PRINTSTRING_CENTER);
|
2020-07-03 10:09:13 +02:00
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
sprintf(stringBuffer, "%d x %s", quantity, string);
|
2020-08-09 15:25:56 +02:00
|
|
|
drawString(400, 550, stringBuffer, D3DCOLOR_ARGB(255, 216, 117, 49), PRINTSTRING_CENTER);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
objectIndex++;
|
|
|
|
if (objectIndex == numObjects)
|
|
|
|
objectIndex = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
lastRing++;
|
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (drawGuiRect)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw blu box
|
|
|
|
drawColoredQuad(guiRect.left, guiRect.top, guiRect.right, guiRect.bottom, guiColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
drawLines2D();
|
|
|
|
drawAllStrings();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (g_Inventory.GetType() == INV_TYPE_TITLE && g_GameFlow->TitleType == TITLE_FLYBY && drawLogo)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw main logo
|
|
|
|
float factorX = (float)ScreenWidth / REFERENCE_RES_WIDTH;
|
|
|
|
float factorY = (float)ScreenHeight / REFERENCE_RES_HEIGHT;
|
|
|
|
|
|
|
|
RECT rect;
|
|
|
|
rect.left = 250 * factorX;
|
|
|
|
rect.right = 550 * factorX;
|
|
|
|
rect.top = 50 * factorY;
|
|
|
|
rect.bottom = 200 * factorY;
|
|
|
|
|
|
|
|
m_spriteBatch->Begin(SpriteSortMode_BackToFront, m_states->Additive());
|
|
|
|
m_spriteBatch->Draw(m_logo.ShaderResourceView.Get(), rect, Vector4::One);
|
|
|
|
m_spriteBatch->End();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawFullScreenQuad(ID3D11ShaderResourceView* texture, DirectX::SimpleMath::Vector3 color, bool cinematicBars)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
RendererVertex vertices[4];
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (!cinematicBars)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
vertices[0].Position.x = -1.0f;
|
|
|
|
vertices[0].Position.y = 1.0f;
|
|
|
|
vertices[0].Position.z = 0.0f;
|
|
|
|
vertices[0].UV.x = 0.0f;
|
|
|
|
vertices[0].UV.y = 0.0f;
|
|
|
|
vertices[0].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
|
|
|
|
vertices[1].Position.x = 1.0f;
|
|
|
|
vertices[1].Position.y = 1.0f;
|
|
|
|
vertices[1].Position.z = 0.0f;
|
|
|
|
vertices[1].UV.x = 1.0f;
|
|
|
|
vertices[1].UV.y = 0.0f;
|
|
|
|
vertices[1].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
|
|
|
|
vertices[2].Position.x = 1.0f;
|
|
|
|
vertices[2].Position.y = -1.0f;
|
|
|
|
vertices[2].Position.z = 0.0f;
|
|
|
|
vertices[2].UV.x = 1.0f;
|
|
|
|
vertices[2].UV.y = 1.0f;
|
|
|
|
vertices[2].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
|
|
|
|
vertices[3].Position.x = -1.0f;
|
|
|
|
vertices[3].Position.y = -1.0f;
|
|
|
|
vertices[3].Position.z = 0.0f;
|
|
|
|
vertices[3].UV.x = 0.0f;
|
|
|
|
vertices[3].UV.y = 1.0f;
|
|
|
|
vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
float cinematicFactor = 0.12f;
|
|
|
|
|
|
|
|
vertices[0].Position.x = -1.0f;
|
|
|
|
vertices[0].Position.y = 1.0f - cinematicFactor * 2;
|
|
|
|
vertices[0].Position.z = 0.0f;
|
|
|
|
vertices[0].UV.x = 0.0f;
|
|
|
|
vertices[0].UV.y = cinematicFactor;
|
|
|
|
vertices[0].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
|
|
|
|
vertices[1].Position.x = 1.0f;
|
|
|
|
vertices[1].Position.y = 1.0f - cinematicFactor * 2;
|
|
|
|
vertices[1].Position.z = 0.0f;
|
|
|
|
vertices[1].UV.x = 1.0f;
|
|
|
|
vertices[1].UV.y = cinematicFactor;
|
|
|
|
vertices[1].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
|
|
|
|
vertices[2].Position.x = 1.0f;
|
|
|
|
vertices[2].Position.y = -(1.0f - cinematicFactor * 2);
|
|
|
|
vertices[2].Position.z = 0.0f;
|
|
|
|
vertices[2].UV.x = 1.0f;
|
|
|
|
vertices[2].UV.y = 1.0f - cinematicFactor;
|
|
|
|
vertices[2].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
|
|
|
|
vertices[3].Position.x = -1.0f;
|
|
|
|
vertices[3].Position.y = -(1.0f - cinematicFactor * 2);
|
|
|
|
vertices[3].Position.z = 0.0f;
|
|
|
|
vertices[3].UV.x = 0.0f;
|
|
|
|
vertices[3].UV.y = 1.0f - cinematicFactor;
|
|
|
|
vertices[3].Color = Vector4(color.x, color.y, color.z, 1.0f);
|
|
|
|
}
|
|
|
|
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsFullScreenQuad.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psFullScreenQuad.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_context->PSSetShaderResources(0, 1, &texture);
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicClamp();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_primitiveBatch->Begin();
|
|
|
|
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
|
|
|
|
m_primitiveBatch->End();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawRopes()
|
|
|
|
{
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int n = 0; n < NumRopes; n++)
|
|
|
|
{
|
|
|
|
ROPE_STRUCT *rope = &Ropes[n];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (rope->active)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Original algorithm:
|
|
|
|
// 1) Transform segment coordinates from 3D to 2D + depth
|
|
|
|
// 2) Get dx, dy and the segment length
|
|
|
|
// 3) Get sine and cosine from dx / length and dy / length
|
|
|
|
// 4) Calculate a scale factor
|
|
|
|
// 5) Get the coordinates of the 4 corners of each sprite iteratively
|
|
|
|
// 6) Last step only for us, unproject back to 3D coordinates
|
|
|
|
|
|
|
|
// Tranform rope points
|
|
|
|
Vector3 projected[24];
|
|
|
|
Matrix world = Matrix::Identity;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < 24; i++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Vector3 absolutePosition = Vector3(rope->position.x + rope->segment[i].x / 65536.0f,
|
|
|
|
rope->position.y + rope->segment[i].y / 65536.0f,
|
|
|
|
rope->position.z + rope->segment[i].z / 65536.0f);
|
|
|
|
|
|
|
|
projected[i] = m_viewportToolkit->Project(absolutePosition, Projection, View, world);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now each rope point is transformed in screen X, Y and Z depth
|
|
|
|
// Let's calculate dx, dy corrections and scaling
|
|
|
|
float dx = projected[1].x - projected[0].x;
|
|
|
|
float dy = projected[1].y - projected[0].y;
|
|
|
|
float length = sqrt(dx * dx + dy * dy);
|
|
|
|
float s = 0;
|
|
|
|
float c = 0;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (length != 0)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
s = -dy / length;
|
|
|
|
c = dx / length;
|
|
|
|
}
|
|
|
|
|
|
|
|
float w = 6.0f;
|
2020-07-03 10:09:13 +02:00
|
|
|
if (projected[0].z)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
w = 6.0f * PhdPerspective / projected[0].z / 65536.0f;
|
|
|
|
if (w < 3)
|
|
|
|
w = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
float sdx = s * w;
|
|
|
|
float sdy = c * w;
|
|
|
|
|
|
|
|
float x1 = projected[0].x - sdx;
|
|
|
|
float y1 = projected[0].y - sdy;
|
|
|
|
|
|
|
|
float x2 = projected[0].x + sdx;
|
|
|
|
float y2 = projected[0].y + sdy;
|
|
|
|
|
|
|
|
float depth = projected[0].z;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = 0; j < 24; j++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Vector3 p1 = m_viewportToolkit->Unproject(Vector3(x1, y1, depth), Projection, View, world);
|
|
|
|
Vector3 p2 = m_viewportToolkit->Unproject(Vector3(x2, y2, depth), Projection, View, world);
|
|
|
|
|
|
|
|
dx = projected[j].x - projected[j - 1].x;
|
|
|
|
dy = projected[j].y - projected[j - 1].y;
|
|
|
|
length = sqrt(dx * dx + dy * dy);
|
|
|
|
s = 0;
|
|
|
|
c = 0;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (length != 0)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
s = -dy / length;
|
|
|
|
c = dx / length;
|
|
|
|
}
|
|
|
|
|
|
|
|
w = 6.0f;
|
2020-07-03 10:09:13 +02:00
|
|
|
if (projected[j].z)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
w = 6.0f * PhdPerspective / projected[j].z / 65536.0f;
|
|
|
|
if (w < 3)
|
|
|
|
w = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
float sdx = s * w;
|
|
|
|
float sdy = c * w;
|
|
|
|
|
|
|
|
float x3 = projected[j].x - sdx;
|
|
|
|
float y3 = projected[j].y - sdy;
|
|
|
|
|
|
|
|
float x4 = projected[j].x + sdx;
|
|
|
|
float y4 = projected[j].y + sdy;
|
|
|
|
|
|
|
|
depth = projected[j].z;
|
|
|
|
|
|
|
|
Vector3 p3 = m_viewportToolkit->Unproject(Vector3(x3, y3, depth), Projection, View, world);
|
|
|
|
Vector3 p4 = m_viewportToolkit->Unproject(Vector3(x4, y4, depth), Projection, View, world);
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
addSprite3D(&m_sprites[20],
|
2020-06-27 19:48:50 +02:00
|
|
|
Vector3(p1.x, p1.y, p1.z),
|
|
|
|
Vector3(p2.x, p2.y, p2.z),
|
|
|
|
Vector3(p3.x, p3.y, p3.z),
|
|
|
|
Vector3(p4.x, p4.y, p4.z),
|
|
|
|
Vector4(0.5f, 0.5f, 0.5f, 1.0f), 0, 1, 0, 0, BLENDMODE_OPAQUE);
|
|
|
|
|
|
|
|
x1 = x4;
|
|
|
|
y1 = y4;
|
|
|
|
x2 = x3;
|
|
|
|
y2 = y3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawLines2D()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->RSSetState(m_states->CullNone());
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthRead(), 0);
|
|
|
|
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsSolid.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psSolid.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
Matrix world = Matrix::CreateOrthographicOffCenter(0, ScreenWidth, ScreenHeight, 0, m_viewport.MinDepth, m_viewport.MaxDepth);
|
|
|
|
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_primitiveBatch->Begin();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < m_lines2DToDraw.size(); i++)
|
|
|
|
{
|
|
|
|
RendererLine2D *line = m_lines2DToDraw[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
RendererVertex v1;
|
|
|
|
v1.Position.x = line->Vertices[0].x;
|
|
|
|
v1.Position.y = line->Vertices[0].y;
|
|
|
|
v1.Position.z = 1.0f;
|
|
|
|
v1.Color.x = line->Color.x / 255.0f;
|
|
|
|
v1.Color.y = line->Color.y / 255.0f;
|
|
|
|
v1.Color.z = line->Color.z / 255.0f;
|
|
|
|
v1.Color.w = line->Color.w / 255.0f;
|
|
|
|
|
|
|
|
RendererVertex v2;
|
|
|
|
v2.Position.x = line->Vertices[1].x;
|
|
|
|
v2.Position.y = line->Vertices[1].y;
|
|
|
|
v2.Position.z = 1.0f;
|
|
|
|
v2.Color.x = line->Color.x / 255.0f;
|
|
|
|
v2.Color.y = line->Color.y / 255.0f;
|
|
|
|
v2.Color.z = line->Color.z / 255.0f;
|
|
|
|
v2.Color.w = line->Color.w / 255.0f;
|
|
|
|
|
|
|
|
v1.Position = Vector3::Transform(v1.Position, world);
|
|
|
|
v2.Position = Vector3::Transform(v2.Position, world);
|
|
|
|
|
|
|
|
v1.Position.z = 0.5f;
|
|
|
|
v2.Position.z = 0.5f;
|
|
|
|
|
|
|
|
m_primitiveBatch->DrawLine(v1, v2);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_primitiveBatch->End();
|
|
|
|
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawSpiders()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
/*XMMATRIX world;
|
|
|
|
UINT cPasses = 1;
|
|
|
|
|
|
|
|
if (Objects[ID_SPIDERS_EMITTER].loaded)
|
|
|
|
{
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO* obj = &Objects[ID_SPIDERS_EMITTER];
|
2020-06-27 19:48:50 +02:00
|
|
|
RendererObject* moveableObj = m_moveableObjects[ID_SPIDERS_EMITTER].get();
|
|
|
|
short* meshPtr = Meshes[Objects[ID_SPIDERS_EMITTER].meshIndex + ((Wibble >> 2) & 2)];
|
|
|
|
RendererMesh* mesh = m_meshPointersToMesh[meshPtr];
|
|
|
|
RendererBucket* bucket = mesh->GetBucket(bucketIndex);
|
|
|
|
|
|
|
|
if (bucket->NumVertices == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
setGpuStateForBucket(bucketIndex);
|
|
|
|
|
|
|
|
m_device->SetStreamSource(0, bucket->GetVertexBuffer(), 0, sizeof(RendererVertex));
|
|
|
|
m_device->SetIndices(bucket->GetIndexBuffer());
|
|
|
|
|
|
|
|
LPD3DXEFFECT effect;
|
|
|
|
if (pass == RENDERER_PASS_SHADOW_MAP)
|
|
|
|
effect = m_shaderDepth->GetEffect();
|
|
|
|
else if (pass == RENDERER_PASS_RECONSTRUCT_DEPTH)
|
|
|
|
effect = m_shaderReconstructZBuffer->GetEffect();
|
|
|
|
else if (pass == RENDERER_PASS_GBUFFER)
|
|
|
|
effect = m_shaderFillGBuffer->GetEffect();
|
|
|
|
else
|
|
|
|
effect = m_shaderTransparent->GetEffect();
|
|
|
|
|
|
|
|
effect->SetBool(effect->GetParameterByName(NULL, "UseSkinning"), false);
|
|
|
|
effect->SetInt(effect->GetParameterByName(NULL, "ModelType"), MODEL_TYPE_MOVEABLE);
|
|
|
|
|
|
|
|
if (bucketIndex == RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKET_SOLID_DS)
|
|
|
|
effect->SetInt(effect->GetParameterByName(NULL, "BlendMode"), BLENDMODE_OPAQUE);
|
|
|
|
else
|
|
|
|
effect->SetInt(effect->GetParameterByName(NULL, "BlendMode"), BLENDMODE_ALPHATEST);
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_SPIDERS; i++)
|
|
|
|
{
|
|
|
|
SPIDER_STRUCT* spider = &Spiders[i];
|
|
|
|
|
|
|
|
if (spider->on)
|
|
|
|
{
|
|
|
|
XMMATRIXTranslation(&m_tempTranslation, spider->pos.xPos, spider->pos.yPos, spider->pos.zPos);
|
|
|
|
XMMATRIXRotationYawPitchRoll(&m_tempRotation, spider->pos.yRot, spider->pos.xRot, spider->pos.zRot);
|
|
|
|
XMMATRIXMultiply(&m_tempWorld, &m_tempRotation, &m_tempTranslation);
|
|
|
|
effect->SetMatrix(effect->GetParameterByName(NULL, "World"), &m_tempWorld);
|
|
|
|
|
|
|
|
effect->SetVector(effect->GetParameterByName(NULL, "AmbientLight"), &m_rooms[spider->roomNumber]->AmbientLight);
|
|
|
|
|
|
|
|
for (int iPass = 0; iPass < cPasses; iPass++)
|
|
|
|
{
|
|
|
|
effect->BeginPass(iPass);
|
|
|
|
effect->CommitChanges();
|
|
|
|
|
2020-07-03 07:05:33 +02:00
|
|
|
drawPrimitives(D3DPT_TRIANGLELIST, 0, 0, bucket->NumVertices, 0, bucket->Indices.size() / 3);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
effect->EndPass();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawRats()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (Objects[ID_RATS_EMITTER].loaded)
|
|
|
|
{
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO *obj = &Objects[ID_RATS_EMITTER];
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &moveableObj = *m_moveableObjects[ID_RATS_EMITTER];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
for (int m = 0; m < 32; m++)
|
|
|
|
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < NUM_RATS; i++)
|
|
|
|
{
|
|
|
|
RAT_STRUCT *rat = &Rats[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (rat->on)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = getMesh(Objects[ID_RATS_EMITTER].meshIndex + (rand() % 8));
|
2020-06-27 19:48:50 +02:00
|
|
|
Matrix translation = Matrix::CreateTranslation(rat->pos.xPos, rat->pos.yPos, rat->pos.zPos);
|
|
|
|
Matrix rotation = Matrix::CreateFromYawPitchRoll(rat->pos.yRot, rat->pos.xRot, rat->pos.zRot);
|
|
|
|
Matrix world = rotation * translation;
|
|
|
|
|
|
|
|
m_stItem.World = world;
|
|
|
|
m_stItem.Position = Vector4(rat->pos.xPos, rat->pos.yPos, rat->pos.zPos, 1.0f);
|
|
|
|
m_stItem.AmbientLight = m_rooms[rat->roomNumber].AmbientLight;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int b = 0; b < 2; b++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[b];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-05 06:20:36 +02:00
|
|
|
if (bucket->Vertices.size() == 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
|
|
|
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawBats()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (Objects[ID_BATS_EMITTER].loaded)
|
|
|
|
{
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO *obj = &Objects[ID_BATS_EMITTER];
|
2020-07-26 08:58:44 +02:00
|
|
|
RendererObject &moveableObj = *m_moveableObjects[ID_BATS_EMITTER];
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererMesh *mesh = getMesh(Objects[ID_BATS_EMITTER].meshIndex + (-GlobalCounter & 3));
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
for (int m = 0; m < 32; m++)
|
|
|
|
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int b = 0; b < 2; b++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[b];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-05 06:20:36 +02:00
|
|
|
if (bucket->Vertices.size() == 0)
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < NUM_BATS; i++)
|
|
|
|
{
|
|
|
|
BAT_STRUCT *bat = &Bats[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (bat->on)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Matrix translation = Matrix::CreateTranslation(bat->pos.xPos, bat->pos.yPos, bat->pos.zPos);
|
|
|
|
Matrix rotation = Matrix::CreateFromYawPitchRoll(bat->pos.yRot, bat->pos.xRot, bat->pos.zRot);
|
|
|
|
Matrix world = rotation * translation;
|
|
|
|
|
|
|
|
m_stItem.World = world;
|
|
|
|
m_stItem.Position = Vector4(bat->pos.xPos, bat->pos.yPos, bat->pos.zPos, 1.0f);
|
|
|
|
m_stItem.AmbientLight = m_rooms[bat->roomNumber].AmbientLight;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawLittleBeetles()
|
|
|
|
{
|
2020-08-06 06:51:32 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-08-06 06:51:32 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
|
|
|
if (Objects[ID_LITTLE_BEETLE].loaded)
|
|
|
|
{
|
|
|
|
OBJECT_INFO* obj = &Objects[ID_LITTLE_BEETLE];
|
|
|
|
RendererObject& moveableObj = *m_moveableObjects[ID_LITTLE_BEETLE];
|
|
|
|
|
|
|
|
for (int m = 0; m < 32; m++)
|
|
|
|
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_LITTLE_BETTLES; i++)
|
|
|
|
{
|
|
|
|
BEETLE_INFO* beetle = &LittleBeetles[i];
|
|
|
|
|
|
|
|
if (beetle->on)
|
|
|
|
{
|
|
|
|
RendererMesh* mesh = getMesh(Objects[ID_LITTLE_BEETLE].meshIndex);
|
|
|
|
Matrix translation = Matrix::CreateTranslation(beetle->pos.xPos, beetle->pos.yPos, beetle->pos.zPos);
|
|
|
|
Matrix rotation = Matrix::CreateFromYawPitchRoll(beetle->pos.yRot, beetle->pos.xRot, beetle->pos.zRot);
|
|
|
|
Matrix world = rotation * translation;
|
|
|
|
|
|
|
|
m_stItem.World = world;
|
|
|
|
m_stItem.Position = Vector4(beetle->pos.xPos, beetle->pos.yPos, beetle->pos.zPos, 1.0f);
|
|
|
|
m_stItem.AmbientLight = m_rooms[beetle->roomNumber].AmbientLight;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem,m_context.Get());
|
2020-08-06 06:51:32 +02:00
|
|
|
|
|
|
|
for (int b = 0; b < 2; b++)
|
|
|
|
{
|
|
|
|
RendererBucket* bucket = &mesh->Buckets[b];
|
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::doSnow()
|
|
|
|
{
|
2020-07-03 10:09:13 +02:00
|
|
|
if (m_firstWeather)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
for (int i = 0; i < NUM_SNOW_PARTICLES; i++)
|
|
|
|
m_snow[i].Reset = true;
|
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < NUM_SNOW_PARTICLES; i++)
|
|
|
|
{
|
|
|
|
RendererWeatherParticle *snow = &m_snow[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (snow->Reset)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
snow->X = LaraItem->pos.xPos + rand() % WEATHER_RADIUS - WEATHER_RADIUS / 2.0f;
|
|
|
|
snow->Y = LaraItem->pos.yPos - (m_firstWeather ? rand() % WEATHER_HEIGHT : WEATHER_HEIGHT) + (rand() % 512);
|
|
|
|
snow->Z = LaraItem->pos.zPos + rand() % WEATHER_RADIUS - WEATHER_RADIUS / 2.0f;
|
|
|
|
|
|
|
|
// Check if in inside room
|
|
|
|
short roomNumber = Camera.pos.roomNumber;
|
2020-07-03 10:09:13 +02:00
|
|
|
FLOOR_INFO *floor = GetFloor(snow->X, snow->Y, snow->Z, &roomNumber);
|
2020-07-21 09:56:47 +02:00
|
|
|
ROOM_INFO *room = &g_Level.Rooms[roomNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
if (!(room->flags & ENV_FLAG_OUTSIDE))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
snow->Size = SNOW_DELTA_Y + (rand() % 64);
|
|
|
|
snow->AngleH = (rand() % SNOW_MAX_ANGLE_H) * RADIAN;
|
|
|
|
snow->AngleV = (rand() % SNOW_MAX_ANGLE_V) * RADIAN;
|
|
|
|
snow->Reset = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
float radius = snow->Size * sin(snow->AngleV);
|
|
|
|
|
|
|
|
float dx = sin(snow->AngleH) * radius;
|
|
|
|
float dz = cos(snow->AngleH) * radius;
|
|
|
|
|
|
|
|
snow->X += dx;
|
|
|
|
snow->Y += SNOW_DELTA_Y;
|
|
|
|
snow->Z += dz;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (snow->X <= 0 || snow->Z <= 0 || snow->X >= 100 * 1024.0f || snow->Z >= 100 * 1024.0f)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
snow->Reset = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
addSpriteBillboard(&m_sprites[Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST], Vector3(snow->X, snow->Y, snow->Z), Vector4(1, 1, 1, 1),
|
2020-06-27 19:48:50 +02:00
|
|
|
0.0f, 1.0f, SNOW_SIZE, SNOW_SIZE,
|
|
|
|
BLENDMODE_ALPHABLEND);
|
|
|
|
|
|
|
|
short roomNumber = Camera.pos.roomNumber;
|
2020-07-03 10:09:13 +02:00
|
|
|
FLOOR_INFO *floor = GetFloor(snow->X, snow->Y, snow->Z, &roomNumber);
|
2020-07-21 09:56:47 +02:00
|
|
|
ROOM_INFO *room = &g_Level.Rooms[roomNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
if (snow->Y >= room->y + room->minfloor)
|
|
|
|
snow->Reset = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_firstWeather = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::doRain()
|
|
|
|
{
|
2020-07-03 10:09:13 +02:00
|
|
|
if (m_firstWeather)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < NUM_RAIN_DROPS; i++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_rain[i].Reset = true;
|
|
|
|
m_rain[i].Draw = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < NUM_RAIN_DROPS; i++)
|
|
|
|
{
|
|
|
|
RendererWeatherParticle *drop = &m_rain[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (drop->Reset)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
drop->Draw = true;
|
|
|
|
|
|
|
|
drop->X = LaraItem->pos.xPos + rand() % WEATHER_RADIUS - WEATHER_RADIUS / 2.0f;
|
|
|
|
drop->Y = LaraItem->pos.yPos - (m_firstWeather ? rand() % WEATHER_HEIGHT : WEATHER_HEIGHT);
|
|
|
|
drop->Z = LaraItem->pos.zPos + rand() % WEATHER_RADIUS - WEATHER_RADIUS / 2.0f;
|
|
|
|
|
|
|
|
// Check if in inside room
|
|
|
|
short roomNumber = Camera.pos.roomNumber;
|
2020-07-03 10:09:13 +02:00
|
|
|
FLOOR_INFO *floor = GetFloor(drop->X, drop->Y, drop->Z, &roomNumber);
|
2020-07-21 09:56:47 +02:00
|
|
|
ROOM_INFO *room = &g_Level.Rooms[roomNumber];
|
2020-07-03 10:09:13 +02:00
|
|
|
if (!(room->flags & ENV_FLAG_OUTSIDE))
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
drop->Reset = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
drop->Size = RAIN_SIZE + (rand() % 64);
|
|
|
|
drop->AngleH = (rand() % RAIN_MAX_ANGLE_H) * RADIAN;
|
|
|
|
drop->AngleV = (rand() % RAIN_MAX_ANGLE_V) * RADIAN;
|
|
|
|
drop->Reset = false;
|
|
|
|
}
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
float x1 = drop->X;
|
|
|
|
float y1 = drop->Y;
|
|
|
|
float z1 = drop->Z;
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
float radius = drop->Size * sin(drop->AngleV);
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
float dx = sin(drop->AngleH) * radius;
|
|
|
|
float dy = drop->Size * cos(drop->AngleV);
|
|
|
|
float dz = cos(drop->AngleH) * radius;
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
drop->X += dx;
|
|
|
|
drop->Y += RAIN_DELTA_Y;
|
|
|
|
drop->Z += dz;
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
if (drop->Draw)
|
2020-08-09 15:25:56 +02:00
|
|
|
addLine3D(Vector3(x1, y1, z1), Vector3(drop->X, drop->Y, drop->Z), Vector4(RAIN_COLOR, RAIN_COLOR, RAIN_COLOR, 1.0f));
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
// If rain drop has hit the ground, then reset it and add a little drip
|
|
|
|
short roomNumber = Camera.pos.roomNumber;
|
2020-07-03 10:09:13 +02:00
|
|
|
FLOOR_INFO *floor = GetFloor(drop->X, drop->Y, drop->Z, &roomNumber);
|
2020-07-21 09:56:47 +02:00
|
|
|
ROOM_INFO *room = &g_Level.Rooms[roomNumber];
|
2020-07-03 10:09:13 +02:00
|
|
|
if (drop->Y >= room->y + room->minfloor)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
drop->Reset = true;
|
|
|
|
AddWaterSparks(drop->X, room->y + room->minfloor, drop->Z, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_firstWeather = false;
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawLines3D()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->RSSetState(m_states->CullNone());
|
|
|
|
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthRead(), 0);
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsSolid.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psSolid.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_primitiveBatch->Begin();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < m_lines3DToDraw.size(); i++)
|
|
|
|
{
|
|
|
|
RendererLine3D *line = m_lines3DToDraw[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
RendererVertex v1;
|
|
|
|
v1.Position = line->start;
|
|
|
|
v1.Color = line->color;
|
|
|
|
|
|
|
|
RendererVertex v2;
|
|
|
|
v2.Position = line->end;
|
|
|
|
v2.Color = line->color;
|
|
|
|
m_primitiveBatch->DrawLine(v1, v2);
|
|
|
|
}
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
m_primitiveBatch->End();
|
|
|
|
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::addLine3D(Vector3 start, Vector3 end, Vector4 color)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
if (m_nextLine3D >= MAX_LINES_3D)
|
|
|
|
return;
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererLine3D *line = &m_lines3DBuffer[m_nextLine3D++];
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
line->start = start;
|
|
|
|
line->end = end;
|
|
|
|
line->color = color;
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
m_lines3DToDraw.push_back(line);
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderLoadingScreen(std::wstring& fileName)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
return;
|
2020-07-03 10:09:13 +02:00
|
|
|
/*
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
Texture2D texture = Texture2D(m_device, fileName);
|
|
|
|
|
|
|
|
m_fadeStatus = RENDERER_FADE_STATUS::FADE_IN;
|
|
|
|
m_fadeFactor = 0.0f;
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
while (true) {
|
|
|
|
if (m_fadeStatus == RENDERER_FADE_STATUS::FADE_IN && m_fadeFactor < 1.0f)
|
|
|
|
m_fadeFactor += FADE_FACTOR;
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
if (m_fadeStatus == RENDERER_FADE_STATUS::FADE_OUT && m_fadeFactor > 0.0f)
|
|
|
|
m_fadeFactor -= FADE_FACTOR;
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
// Set basic render states
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
// Clear screen
|
|
|
|
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
|
|
|
|
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
2020-01-08 20:57:33 +01:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
// Bind the back buffer
|
|
|
|
m_context->OMSetRenderTargets(1, &m_backBufferRTV, m_depthStencilView);
|
|
|
|
m_context->RSSetViewports(1, &m_viewport);
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw the full screen background
|
|
|
|
drawFullScreenQuad(texture.ShaderResourceView.GetAddressOf(), Vector3(m_fadeFactor, m_fadeFactor, m_fadeFactor), false);
|
|
|
|
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
m_swapChain->Present(0, 0);
|
|
|
|
m_context->ClearState();
|
|
|
|
if (m_fadeStatus == RENDERER_FADE_STATUS::FADE_IN && m_fadeFactor >= 1.0f) {
|
|
|
|
m_fadeStatus = RENDERER_FADE_STATUS::NO_FADE;
|
|
|
|
m_fadeFactor = 1.0f;
|
|
|
|
}
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
if (m_fadeStatus == RENDERER_FADE_STATUS::NO_FADE && m_progress == 100) {
|
|
|
|
m_fadeStatus = RENDERER_FADE_STATUS::FADE_OUT;
|
|
|
|
m_fadeFactor = 1.0f;
|
|
|
|
}
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
if (m_fadeStatus == RENDERER_FADE_STATUS::FADE_OUT && m_fadeFactor <= 0.0f) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::addDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
if (m_nextLight >= MAX_LIGHTS)
|
|
|
|
return;
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererLight *dynamicLight = &m_lights[m_nextLight++];
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
dynamicLight->Position = Vector3(float(x), float(y), float(z));
|
|
|
|
dynamicLight->Color = Vector3(r / 255.0f, g / 255.0f, b / 255.0f);
|
|
|
|
dynamicLight->Out = falloff * 256.0f;
|
|
|
|
dynamicLight->Type = LIGHT_TYPES::LIGHT_TYPE_POINT;
|
|
|
|
dynamicLight->Dynamic = true;
|
|
|
|
dynamicLight->Intensity = falloff / 2;
|
2020-06-21 14:27:12 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
m_dynamicLights.push_back(dynamicLight);
|
|
|
|
//NumDynamics++;
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::clearDynamicLights()
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_dynamicLights.clear();
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Reset GPU state
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
2020-06-30 10:25:41 +02:00
|
|
|
m_context->OMSetRenderTargets(1, &target, depthTarget);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->RSSetViewports(1, &m_viewport);
|
|
|
|
drawFullScreenQuad(texture, Vector3(fade, fade, fade), false);
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderInventory()
|
|
|
|
{
|
2020-07-03 10:09:13 +02:00
|
|
|
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
|
|
|
|
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
|
2020-08-09 15:25:56 +02:00
|
|
|
renderInventoryScene(m_backBufferRTV, m_depthStencilView, m_dumpScreenRenderTarget.ShaderResourceView.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_swapChain->Present(0, 0);
|
2020-06-30 10:25:41 +02:00
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderTitle()
|
|
|
|
{
|
2020-07-03 10:09:13 +02:00
|
|
|
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
|
|
|
|
m_context->ClearRenderTargetView(m_backBufferRTV, Colors::Black);
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
renderScene(m_backBufferRTV, m_depthStencilView, gameCamera);
|
2020-07-03 10:09:13 +02:00
|
|
|
m_context->ClearDepthStencilView(m_depthStencilView, D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
renderInventoryScene(m_backBufferRTV, m_depthStencilView, nullptr);
|
2020-06-30 10:25:41 +02:00
|
|
|
m_swapChain->Present(0, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
using ns = std::chrono::nanoseconds;
|
|
|
|
using get_time = std::chrono::steady_clock;
|
|
|
|
m_timeUpdate = 0;
|
|
|
|
m_timeDraw = 0;
|
|
|
|
m_timeFrame = 0;
|
|
|
|
m_numDrawCalls = 0;
|
|
|
|
m_nextLight = 0;
|
|
|
|
m_nextSprite = 0;
|
|
|
|
m_nextLine3D = 0;
|
|
|
|
m_nextLine2D = 0;
|
|
|
|
|
|
|
|
m_currentCausticsFrame++;
|
|
|
|
m_currentCausticsFrame %= 32;
|
|
|
|
|
|
|
|
m_strings.clear();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
GameScriptLevel *level = g_GameFlow->GetLevel(CurrentLevel);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-01 08:46:07 +02:00
|
|
|
m_stLights.CameraPosition = view.camera.WorldPosition;
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Prepare the scene to draw
|
|
|
|
auto time1 = std::chrono::high_resolution_clock::now();
|
2020-07-01 08:46:07 +02:00
|
|
|
//prepareCameraForFrame();
|
2020-06-27 19:48:50 +02:00
|
|
|
clearSceneItems();
|
2020-07-01 08:46:07 +02:00
|
|
|
collectRooms(view);
|
2020-08-09 15:25:56 +02:00
|
|
|
updateLaraAnimations(false);
|
2020-07-24 07:03:36 +02:00
|
|
|
updateItemsAnimations(view);
|
|
|
|
updateEffects(view);
|
2020-06-27 19:48:50 +02:00
|
|
|
if (g_Configuration.EnableShadows)
|
2020-08-09 15:25:56 +02:00
|
|
|
renderShadowMap(view);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_items[Lara.itemNumber].Item = LaraItem;
|
2020-07-01 08:46:07 +02:00
|
|
|
collectLightsForItem(LaraItem->roomNumber, &m_items[Lara.itemNumber], view);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Update animated textures every 2 frames
|
|
|
|
if (GnFrameCounter % 2 == 0)
|
|
|
|
updateAnimatedTextures();
|
|
|
|
|
|
|
|
auto time2 = std::chrono::high_resolution_clock::now();
|
|
|
|
m_timeUpdate = (std::chrono::duration_cast<ns>(time2 - time1)).count() / 1000000;
|
|
|
|
time1 = time2;
|
|
|
|
|
|
|
|
// Draw shadow map
|
|
|
|
|
|
|
|
// Reset GPU state
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
|
|
|
|
// Bind and clear render target
|
|
|
|
|
2020-06-30 10:25:41 +02:00
|
|
|
m_context->ClearRenderTargetView(target, Colors::Black);
|
|
|
|
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
|
|
|
m_context->OMSetRenderTargets(1, &target, depthTarget);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-01 16:49:53 +02:00
|
|
|
m_context->RSSetViewports(1, &view.viewport);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Opaque geometry
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
2020-07-01 08:46:07 +02:00
|
|
|
CCameraMatrixBuffer cameraConstantBuffer;
|
2020-07-01 21:13:07 +02:00
|
|
|
view.fillConstantBuffer(cameraConstantBuffer);
|
2020-07-01 08:46:07 +02:00
|
|
|
cameraConstantBuffer.Frame = GnFrameCounter;
|
2020-07-21 09:56:47 +02:00
|
|
|
cameraConstantBuffer.CameraUnderwater = g_Level.Rooms[cameraConstantBuffer.RoomNumber].flags & ENV_FLAG_WATER;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbCameraMatrices.updateData(cameraConstantBuffer, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
|
2020-07-01 08:46:07 +02:00
|
|
|
drawHorizonAndSky(depthTarget);
|
|
|
|
drawRooms(false, false, view);
|
|
|
|
drawRooms(false, true, view);
|
|
|
|
drawStatics(false, view);
|
2020-06-27 19:48:50 +02:00
|
|
|
drawLara(false, false);
|
2020-07-01 08:46:07 +02:00
|
|
|
drawItems(false, false, view);
|
|
|
|
drawItems(false, true, view);
|
2020-06-27 19:48:50 +02:00
|
|
|
drawEffects(false);
|
|
|
|
drawGunFlashes();
|
|
|
|
drawGunShells();
|
|
|
|
drawBaddieGunflashes();
|
|
|
|
drawDebris(false);
|
|
|
|
drawBats();
|
|
|
|
drawRats();
|
|
|
|
drawSpiders();
|
2020-08-06 06:51:32 +02:00
|
|
|
drawLittleBeetles();
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Transparent geometry
|
|
|
|
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthRead(), 0);
|
|
|
|
|
2020-07-01 08:46:07 +02:00
|
|
|
drawRooms(true, false, view);
|
|
|
|
drawRooms(true, true, view);
|
|
|
|
drawStatics(true, view);
|
2020-06-27 19:48:50 +02:00
|
|
|
drawLara(true, false);
|
2020-07-01 08:46:07 +02:00
|
|
|
drawItems(true, false, view);
|
|
|
|
drawItems(true, true, view);
|
2020-06-27 19:48:50 +02:00
|
|
|
drawEffects(true);
|
|
|
|
drawWaterfalls();
|
|
|
|
drawDebris(true);
|
|
|
|
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
|
|
|
|
// Do special effects and weather
|
|
|
|
drawFires();
|
|
|
|
drawSmokes();
|
|
|
|
drawSmokeParticles();
|
|
|
|
drawSparkParticles();
|
|
|
|
drawExplosionParticles();
|
|
|
|
drawFootprints();
|
|
|
|
drawDripParticles();
|
|
|
|
drawBlood();
|
|
|
|
drawSparks();
|
|
|
|
drawBubbles();
|
|
|
|
drawDrips();
|
|
|
|
drawRipples();
|
|
|
|
drawUnderwaterDust();
|
|
|
|
drawSplahes();
|
|
|
|
drawShockwaves();
|
|
|
|
drawEnergyArcs();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
switch (level->Weather)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
case WEATHER_NORMAL:
|
|
|
|
// no weather in normal
|
|
|
|
break;
|
|
|
|
case WEATHER_RAIN:
|
|
|
|
doRain();
|
|
|
|
break;
|
|
|
|
case WEATHER_SNOW:
|
|
|
|
doSnow();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
drawRopes();
|
|
|
|
drawSprites();
|
|
|
|
drawLines3D();
|
|
|
|
|
|
|
|
time2 = std::chrono::high_resolution_clock::now();
|
|
|
|
m_timeFrame = (std::chrono::duration_cast<ns>(time2 - time1)).count() / 1000000;
|
|
|
|
time1 = time2;
|
|
|
|
|
|
|
|
// Bars
|
|
|
|
int flash = FlashIt();
|
|
|
|
if (DashTimer < 120)
|
2020-08-09 15:25:56 +02:00
|
|
|
drawBar(DashTimer / 120.0f, g_DashBar);
|
2020-08-04 20:51:47 +10:00
|
|
|
UpdateHealthBar(flash);
|
2020-06-27 19:48:50 +02:00
|
|
|
UpdateAirBar(flash);
|
|
|
|
DrawAllPickups();
|
|
|
|
|
|
|
|
drawLines2D();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (CurrentLevel != 0)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Draw binoculars or lasersight
|
|
|
|
drawOverlays();
|
|
|
|
|
|
|
|
m_currentY = 60;
|
2020-01-08 20:57:33 +01:00
|
|
|
#ifdef _DEBUG
|
2020-07-21 09:56:47 +02:00
|
|
|
ROOM_INFO *r = &g_Level.Rooms[LaraItem->roomNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
printDebugMessage("Update time: %d", m_timeUpdate);
|
|
|
|
printDebugMessage("Frame time: %d", m_timeFrame);
|
|
|
|
printDebugMessage("Draw calls: %d", m_numDrawCalls);
|
|
|
|
printDebugMessage("Rooms: %d", m_roomsToDraw.size());
|
|
|
|
printDebugMessage("Items: %d", m_itemsToDraw.size());
|
|
|
|
printDebugMessage("Statics: %d", m_staticsToDraw.size());
|
|
|
|
printDebugMessage("Lights: %d", m_lightsToDraw.size());
|
|
|
|
printDebugMessage("Lara.roomNumber: %d", LaraItem->roomNumber);
|
2020-07-26 08:58:44 +02:00
|
|
|
printDebugMessage("LaraItem.boxNumber: %d", LaraItem->boxNumber);
|
2020-06-27 19:48:50 +02:00
|
|
|
printDebugMessage("Lara.pos: %d %d %d", LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
|
|
|
printDebugMessage("Lara.rot: %d %d %d", LaraItem->pos.xRot, LaraItem->pos.yRot, LaraItem->pos.zRot);
|
|
|
|
printDebugMessage("Lara.animNumber: %d", LaraItem->animNumber);
|
|
|
|
printDebugMessage("Lara.frameNumber: %d", LaraItem->frameNumber);
|
|
|
|
printDebugMessage("Lara.currentAnimState: %d", LaraItem->currentAnimState);
|
|
|
|
printDebugMessage("Lara.requiredAnimState: %d", LaraItem->requiredAnimState);
|
|
|
|
printDebugMessage("Lara.goalAnimState: %d", LaraItem->goalAnimState);
|
|
|
|
printDebugMessage("Lara.weaponItem: %d", Lara.weaponItem);
|
|
|
|
printDebugMessage("Lara.gunType: %d", Lara.gunType);
|
|
|
|
printDebugMessage("Lara.gunStatus: %d", Lara.gunStatus);
|
|
|
|
printDebugMessage("Lara.speed, fallspeed: %d %d", LaraItem->speed, LaraItem->fallspeed);
|
|
|
|
printDebugMessage("Lara.climbStatus: %d", Lara.climbStatus);
|
|
|
|
printDebugMessage("Room: %d %d %d %d", r->x, r->z, r->x + r->xSize * WALL_SIZE, r->z + r->ySize * WALL_SIZE);
|
|
|
|
printDebugMessage("Room.y, minFloor, maxCeiling: %d %d %d ", r->y, r->minfloor, r->maxceiling);
|
|
|
|
printDebugMessage("Camera.pos: %d %d %d", Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
|
|
|
printDebugMessage("Camera.target: %d %d %d", Camera.target.x, Camera.target.y, Camera.target.z);
|
2020-01-08 20:57:33 +01:00
|
|
|
#endif
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
drawAllStrings();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::renderSimpleScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
|
|
|
GameScriptLevel *level = g_GameFlow->GetLevel(CurrentLevel);
|
2020-07-01 08:46:07 +02:00
|
|
|
|
|
|
|
collectRooms(view);
|
|
|
|
// Draw shadow map
|
|
|
|
|
|
|
|
// Reset GPU state
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
m_context->RSSetState(m_states->CullCounterClockwise());
|
|
|
|
m_context->OMSetDepthStencilState(m_states->DepthDefault(), 0);
|
|
|
|
|
|
|
|
// Bind and clear render target
|
|
|
|
|
|
|
|
m_context->ClearRenderTargetView(target, Colors::Black);
|
|
|
|
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
|
|
|
m_context->OMSetRenderTargets(1, &target, depthTarget);
|
|
|
|
|
2020-07-01 16:49:53 +02:00
|
|
|
m_context->RSSetViewports(1, &view.viewport);
|
2020-07-01 08:46:07 +02:00
|
|
|
|
|
|
|
// Opaque geometry
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
CCameraMatrixBuffer cameraConstantBuffer;
|
2020-07-01 21:13:07 +02:00
|
|
|
view.fillConstantBuffer(cameraConstantBuffer);
|
2020-07-01 08:46:07 +02:00
|
|
|
cameraConstantBuffer.Frame = GnFrameCounter;
|
2020-07-21 09:56:47 +02:00
|
|
|
cameraConstantBuffer.CameraUnderwater = g_Level.Rooms[cameraConstantBuffer.RoomNumber].flags & ENV_FLAG_WATER;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbCameraMatrices.updateData(cameraConstantBuffer, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(0, 1, m_cbCameraMatrices.get());
|
2020-07-01 08:46:07 +02:00
|
|
|
drawHorizonAndSky(depthTarget);
|
|
|
|
drawRooms(false, false, view);
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::DumpGameScene()
|
|
|
|
{
|
|
|
|
renderScene(m_dumpScreenRenderTarget.RenderTargetView.Get(), m_dumpScreenRenderTarget.DepthStencilView.Get(), gameCamera);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawItems(bool transparent, bool animated, RenderView& view)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
int firstBucket = (transparent ? 2 : 0);
|
|
|
|
int lastBucket = (transparent ? 4 : 2);
|
|
|
|
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererItem *item = &m_items[Lara.itemNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set shaders
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsItems.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psItems.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set texture
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
m_context->PSSetShaderResources(2, 1, (std::get<1>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
2020-07-01 08:46:07 +02:00
|
|
|
m_context->PSSetShaderResources(1, 1, m_reflectionCubemap.ShaderResourceView.GetAddressOf());
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicClamp();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
|
|
|
m_stMisc.AlphaTest = !transparent;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < view.itemsToDraw.size(); i++)
|
|
|
|
{
|
|
|
|
RendererItem *item = view.itemsToDraw[i];
|
|
|
|
RendererRoom &const room = m_rooms[item->Item->roomNumber];
|
|
|
|
RendererObject &moveableObj = *m_moveableObjects[item->Item->objectNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
short objectNumber = item->Item->objectNumber;
|
2020-07-03 10:09:13 +02:00
|
|
|
if (moveableObj.DoNotDraw)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
continue;
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else if (objectNumber == ID_TEETH_SPIKES || objectNumber == ID_RAISING_BLOCK1 || objectNumber == ID_RAISING_BLOCK2)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Raising blocks and teeth spikes are normal animating objects but scaled on Y direction
|
|
|
|
drawScaledSpikes(item, transparent, animated);
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else if (objectNumber >= ID_WATERFALL1 && objectNumber <= ID_WATERFALLSS2)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// We'll draw waterfalls later
|
|
|
|
continue;
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
2020-08-02 19:39:55 +02:00
|
|
|
else if (objectNumber >= ID_WRAITH1 && objectNumber <= ID_WRAITH3)
|
|
|
|
{
|
|
|
|
// Wraiths have some additional special effects
|
|
|
|
drawAnimatingItem(item, transparent, animated);
|
|
|
|
drawWraithExtra(item, transparent, animated);
|
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
drawAnimatingItem(item, transparent, animated);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawAnimatingItem(RendererItem* item, bool transparent, bool animated)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
int firstBucket = (transparent ? 2 : 0);
|
|
|
|
int lastBucket = (transparent ? 4 : 2);
|
2020-07-03 10:09:13 +02:00
|
|
|
if (m_rooms.size() <= item->Item->roomNumber)
|
|
|
|
{
|
2020-08-09 15:25:56 +02:00
|
|
|
return;
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererRoom &const room = m_rooms[item->Item->roomNumber];
|
|
|
|
RendererObject &moveableObj = *m_moveableObjects[item->Item->objectNumber];
|
2020-07-07 07:32:33 +02:00
|
|
|
OBJECT_INFO *obj = &Objects[item->Item->objectNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stItem.World = item->World;
|
|
|
|
m_stItem.Position = Vector4(item->Item->pos.xPos, item->Item->pos.yPos, item->Item->pos.zPos, 1.0f);
|
|
|
|
m_stItem.AmbientLight = room.AmbientLight;
|
|
|
|
memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * 32);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbItem.updateData(m_stItem, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbItem.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbItem.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stLights.NumLights = item->Lights.size();
|
|
|
|
for (int j = 0; j < item->Lights.size(); j++)
|
|
|
|
memcpy(&m_stLights.Lights[j], item->Lights[j], sizeof(ShaderLight));
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbLights.updateData(m_stLights, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->PSSetConstantBuffers(2, 1, m_cbLights.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stMisc.AlphaTest = !transparent;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
if (!(item->Item->meshBits & (1 << k)))
|
|
|
|
continue;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererMesh *mesh;
|
|
|
|
if (obj->meshSwapSlot != -1 && ((item->Item->swapMeshFlags >> k) & 1))
|
|
|
|
{
|
|
|
|
RendererObject &swapMeshObj = *m_moveableObjects[obj->meshSwapSlot];
|
2020-06-28 11:12:52 +02:00
|
|
|
mesh = swapMeshObj.ObjectMeshes[k];
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-28 11:12:52 +02:00
|
|
|
mesh = moveableObj.ObjectMeshes[k];
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = firstBucket; j < lastBucket; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Draw vertices
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawScaledSpikes(RendererItem* item, bool transparent, bool animated)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
short objectNumber = item->Item->objectNumber;
|
2020-07-03 10:09:13 +02:00
|
|
|
if ((item->Item->objectNumber != ID_TEETH_SPIKES || item->Item->itemFlags[1]) && (item->Item->objectNumber != ID_RAISING_BLOCK1 || item->Item->triggerFlags > -1))
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
item->Scale = Matrix::CreateScale(1.0f, item->Item->itemFlags[1] / 4096.0f, 1.0f);
|
|
|
|
item->World = item->Scale * item->Rotation * item->Translation;
|
|
|
|
|
|
|
|
return drawAnimatingItem(item, transparent, animated);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawWraithExtra(RendererItem* item, bool transparent, bool animated)
|
2020-08-02 19:39:55 +02:00
|
|
|
{
|
|
|
|
ITEM_INFO* nativeItem = item->Item;
|
|
|
|
WRAITH_INFO* info = (WRAITH_INFO*)nativeItem->data;
|
|
|
|
|
|
|
|
if (transparent || animated)
|
2020-08-09 15:25:56 +02:00
|
|
|
return ;
|
2020-08-02 19:39:55 +02:00
|
|
|
|
|
|
|
for (int j = 0; j <= 4; j++)
|
|
|
|
{
|
|
|
|
Matrix rotation;
|
|
|
|
|
|
|
|
switch (j)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
rotation = Matrix::CreateRotationY(TO_RAD(-1092));
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
rotation = Matrix::CreateRotationY(TO_RAD(1092));
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
rotation = Matrix::CreateRotationZ(TO_RAD(-1092));
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
rotation = Matrix::CreateRotationZ(TO_RAD(1092));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rotation = Matrix::Identity;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Matrix world = rotation * item->World;
|
|
|
|
|
|
|
|
/*for (int i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
Vector3 p1 = Vector3(info[i].xPos - nativeItem->pos.xPos, info[i].yPos - nativeItem->pos.yPos, info[i].zPos - nativeItem->pos.zPos);
|
|
|
|
Vector3 p2 = Vector3(info[i+1].xPos - info[i ].xPos, info[i + 1].yPos - info[i ].yPos, info[i + 1].zPos - info[i ].zPos);
|
|
|
|
|
|
|
|
p1 = Vector3::Transform(p1, world);
|
|
|
|
p2 = Vector3::Transform(p2, world);
|
|
|
|
|
|
|
|
AddLine3D(p1, p2, Vector4(info[i].r / 255.0f, info[i].g / 255.0f, info[i].b / 255.0f, 1.0f));
|
|
|
|
}*/
|
|
|
|
|
|
|
|
for (int i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
Vector3 p1 = Vector3(info[i].xPos, info[i].yPos, info[i].zPos);
|
|
|
|
Vector3 p2 = Vector3(info[i + 1].xPos , info[i + 1].yPos, info[i + 1].zPos);
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
addLine3D(p1, p2, Vector4(info[i].r / 255.0f, info[i].g / 255.0f, info[i].b / 255.0f, 1.0f));
|
2020-08-02 19:39:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawStatics(bool transparent, RenderView& view)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
//return true;
|
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
int firstBucket = (transparent ? 2 : 0);
|
|
|
|
int lastBucket = (transparent ? 4 : 2);
|
|
|
|
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_staticsVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_staticsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
|
|
|
// Set shaders
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsStatics.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psStatics.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set texture
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_staticsTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
m_context->PSSetShaderResources(2, 1, (std::get<1>(m_staticsTextures[0])).ShaderResourceView.GetAddressOf());
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicClamp();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < view.staticsToDraw.size(); i++)
|
|
|
|
{
|
|
|
|
MESH_INFO *msh = view.staticsToDraw[i]->Mesh;
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (!(msh->flags & 1))
|
|
|
|
continue;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererRoom &const room = m_rooms[view.staticsToDraw[i]->RoomIndex];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &staticObj = *m_staticObjects[msh->staticNumber];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
if (staticObj.ObjectMeshes.size() > 0)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-07-26 08:58:44 +02:00
|
|
|
RendererMesh *mesh = staticObj.ObjectMeshes[0];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
m_stStatic.World = (Matrix::CreateRotationY(TO_RAD(msh->yRot)) * Matrix::CreateTranslation(msh->x, msh->y, msh->z));
|
|
|
|
m_stStatic.Color = Vector4(((msh->shade >> 10) & 0xFF) / 255.0f, ((msh->shade >> 5) & 0xFF) / 255.0f, ((msh->shade >> 0) & 0xFF) / 255.0f, 1.0f);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
for (int j = firstBucket; j < lastBucket; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
2020-07-23 21:38:12 +02:00
|
|
|
|
2020-07-26 08:58:44 +02:00
|
|
|
// Draw vertices
|
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawRooms(bool transparent, bool animated, RenderView& view)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
int firstBucket = (transparent ? 2 : 0);
|
|
|
|
int lastBucket = (transparent ? 4 : 2);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (!animated)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Set vertex buffer
|
|
|
|
m_context->IASetVertexBuffers(0, 1, m_roomsVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_roomsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set shaders
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsRooms.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psRooms.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
// Set texture
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_roomTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
m_context->PSSetShaderResources(3, 1, (std::get<1>(m_roomTextures[0])).ShaderResourceView.GetAddressOf());
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler = m_states->AnisotropicWrap();
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
m_context->PSSetShaderResources(1, 1, m_caustics[m_currentCausticsFrame / 2].ShaderResourceView.GetAddressOf());
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->PSSetSamplers(1, 1, m_shadowSampler.GetAddressOf());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->PSSetShaderResources(2, 1, m_shadowMap.ShaderResourceView.GetAddressOf());
|
|
|
|
|
|
|
|
// Set shadow map data
|
2020-07-03 10:09:13 +02:00
|
|
|
if (m_shadowLight != NULL)
|
|
|
|
{
|
2020-07-23 21:40:07 +02:00
|
|
|
|
2020-06-27 19:48:50 +02:00
|
|
|
memcpy(&m_stShadowMap.Light, m_shadowLight, sizeof(ShaderLight));
|
|
|
|
m_stShadowMap.CastShadows = true;
|
|
|
|
//m_stShadowMap.ViewProjectionInverse = ViewProjection.Invert();
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_stShadowMap.CastShadows = false;
|
|
|
|
}
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbShadowMap.updateData(m_stShadowMap, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(4, 1, m_cbShadowMap.get());
|
|
|
|
m_context->PSSetConstantBuffers(4, 1, m_cbShadowMap.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (animated)
|
|
|
|
m_primitiveBatch->Begin();
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < view.roomsToDraw.size(); i++)
|
|
|
|
{
|
|
|
|
RendererRoom *room = view.roomsToDraw[i];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-01 08:46:07 +02:00
|
|
|
m_stLights.NumLights = view.lightsToDraw.size();
|
|
|
|
for (int j = 0; j < view.lightsToDraw.size(); j++)
|
|
|
|
memcpy(&m_stLights.Lights[j], view.lightsToDraw[j], sizeof(ShaderLight));
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbLights.updateData(m_stLights, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbLights.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stMisc.Caustics = (room->Room->flags & ENV_FLAG_WATER);
|
|
|
|
m_stMisc.AlphaTest = !transparent;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_stRoom.AmbientColor = room->AmbientLight;
|
|
|
|
m_stRoom.water = (room->Room->flags & ENV_FLAG_WATER) != 0 ? 1 : 0;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbRoom.updateData(m_stRoom, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(5, 1, m_cbRoom.get());
|
|
|
|
m_context->PSSetConstantBuffers(5, 1, m_cbRoom.get());
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = firstBucket; j < lastBucket; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket;
|
2020-06-27 19:48:50 +02:00
|
|
|
if (!animated)
|
|
|
|
bucket = &room->Buckets[j];
|
|
|
|
else
|
|
|
|
bucket = &room->AnimatedBuckets[j];
|
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (!animated)
|
|
|
|
{
|
2020-06-29 13:29:45 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int k = 0; k < bucket->Polygons.size(); k++)
|
|
|
|
{
|
|
|
|
RendererPolygon *poly = &bucket->Polygons[k];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
if (poly->Shape == SHAPE_RECTANGLE)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_primitiveBatch->DrawQuad(bucket->Vertices[poly->Indices[0]], bucket->Vertices[poly->Indices[1]],
|
|
|
|
bucket->Vertices[poly->Indices[2]], bucket->Vertices[poly->Indices[3]]);
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_primitiveBatch->DrawTriangle(bucket->Vertices[poly->Indices[0]], bucket->Vertices[poly->Indices[1]],
|
|
|
|
bucket->Vertices[poly->Indices[2]]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (animated)
|
|
|
|
m_primitiveBatch->End();
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::drawHorizonAndSky(ID3D11DepthStencilView* depthTarget)
|
2020-07-03 10:09:13 +02:00
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
// Update the sky
|
2020-07-03 10:09:13 +02:00
|
|
|
GameScriptLevel *level = g_GameFlow->GetLevel(CurrentLevel);
|
2020-06-27 19:48:50 +02:00
|
|
|
Vector4 color = Vector4(SkyColor1.r / 255.0f, SkyColor1.g / 255.0f, SkyColor1.b / 255.0f, 1.0f);
|
|
|
|
|
|
|
|
if (!level->Horizon)
|
2020-08-09 15:25:56 +02:00
|
|
|
return ;
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (BinocularRange)
|
|
|
|
AlterFOV(14560 - BinocularRange);
|
|
|
|
|
|
|
|
// Storm
|
2020-07-03 10:09:13 +02:00
|
|
|
if (level->Storm)
|
|
|
|
{
|
|
|
|
if (LightningCount || LightningRand)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
UpdateStorm();
|
|
|
|
if (StormTimer > -1)
|
|
|
|
StormTimer--;
|
|
|
|
if (!StormTimer)
|
|
|
|
SoundEffect(SFX_THUNDER_RUMBLE, NULL, 0);
|
2020-07-03 10:09:13 +02:00
|
|
|
}
|
|
|
|
else if (!(rand() & 0x7F))
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
LightningCount = (rand() & 0x1F) + 16;
|
|
|
|
dLightningRand = rand() + 256;
|
|
|
|
StormTimer = (rand() & 3) + 12;
|
|
|
|
}
|
|
|
|
|
|
|
|
color = Vector4((SkyStormColor[0]) / 255.0f, SkyStormColor[1] / 255.0f, SkyStormColor[2] / 255.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
ID3D11SamplerState *sampler;
|
2020-06-27 19:48:50 +02:00
|
|
|
UINT stride = sizeof(RendererVertex);
|
|
|
|
UINT offset = 0;
|
|
|
|
|
|
|
|
// Draw the sky
|
|
|
|
Matrix rotation = Matrix::CreateRotationX(PI);
|
|
|
|
|
|
|
|
RendererVertex vertices[4];
|
|
|
|
float size = 9728.0f;
|
|
|
|
|
|
|
|
vertices[0].Position.x = -size / 2.0f;
|
|
|
|
vertices[0].Position.y = 0.0f;
|
|
|
|
vertices[0].Position.z = size / 2.0f;
|
|
|
|
vertices[0].UV.x = 0.0f;
|
|
|
|
vertices[0].UV.y = 0.0f;
|
|
|
|
vertices[0].Color.x = 1.0f;
|
|
|
|
vertices[0].Color.y = 1.0f;
|
|
|
|
vertices[0].Color.z = 1.0f;
|
|
|
|
vertices[0].Color.w = 1.0f;
|
|
|
|
|
|
|
|
vertices[1].Position.x = size / 2.0f;
|
|
|
|
vertices[1].Position.y = 0.0f;
|
|
|
|
vertices[1].Position.z = size / 2.0f;
|
|
|
|
vertices[1].UV.x = 1.0f;
|
|
|
|
vertices[1].UV.y = 0.0f;
|
|
|
|
vertices[1].Color.x = 1.0f;
|
|
|
|
vertices[1].Color.y = 1.0f;
|
|
|
|
vertices[1].Color.z = 1.0f;
|
|
|
|
vertices[1].Color.w = 1.0f;
|
|
|
|
|
|
|
|
vertices[2].Position.x = size / 2.0f;
|
|
|
|
vertices[2].Position.y = 0.0f;
|
|
|
|
vertices[2].Position.z = -size / 2.0f;
|
|
|
|
vertices[2].UV.x = 1.0f;
|
|
|
|
vertices[2].UV.y = 1.0f;
|
|
|
|
vertices[2].Color.x = 1.0f;
|
|
|
|
vertices[2].Color.y = 1.0f;
|
|
|
|
vertices[2].Color.z = 1.0f;
|
|
|
|
vertices[2].Color.w = 1.0f;
|
|
|
|
|
|
|
|
vertices[3].Position.x = -size / 2.0f;
|
|
|
|
vertices[3].Position.y = 0.0f;
|
|
|
|
vertices[3].Position.z = -size / 2.0f;
|
|
|
|
vertices[3].UV.x = 0.0f;
|
|
|
|
vertices[3].UV.y = 1.0f;
|
|
|
|
vertices[3].Color.x = 1.0f;
|
|
|
|
vertices[3].Color.y = 1.0f;
|
|
|
|
vertices[3].Color.z = 1.0f;
|
|
|
|
vertices[3].Color.w = 1.0f;
|
|
|
|
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->VSSetShader(m_vsSky.Get(), NULL, 0);
|
|
|
|
m_context->PSSetShader(m_psSky.Get(), NULL, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stMisc.AlphaTest = true;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_context->PSSetShaderResources(0, 1, m_skyTexture.ShaderResourceView.GetAddressOf());
|
|
|
|
sampler = m_states->AnisotropicClamp();
|
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + SkyPos1 - i * 9728.0f, Camera.pos.y - 1536.0f, Camera.pos.z);
|
|
|
|
Matrix world = rotation * translation;
|
|
|
|
|
|
|
|
m_stStatic.World = (rotation * translation);
|
|
|
|
m_stStatic.Color = color;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbStatic.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_primitiveBatch->Begin();
|
|
|
|
m_primitiveBatch->DrawQuad(vertices[0], vertices[1], vertices[2], vertices[3]);
|
|
|
|
m_primitiveBatch->End();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw horizon
|
2020-07-03 10:09:13 +02:00
|
|
|
if (m_moveableObjects[ID_HORIZON].has_value())
|
|
|
|
{
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
|
|
|
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
2020-08-09 22:15:32 +02:00
|
|
|
m_context->IASetInputLayout(m_inputLayout.Get());
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
|
2020-07-18 14:53:26 +02:00
|
|
|
m_context->PSSetShaderResources(0, 1, (std::get<0>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
|
|
|
m_context->PSSetShaderResources(2, 1, (std::get<1>(m_moveablesTextures[0])).ShaderResourceView.GetAddressOf());
|
2020-06-27 19:48:50 +02:00
|
|
|
sampler = m_states->AnisotropicClamp();
|
|
|
|
m_context->PSSetSamplers(0, 1, &sampler);
|
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
RendererObject &moveableObj = *m_moveableObjects[ID_HORIZON];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stStatic.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
|
|
|
m_stStatic.Position = Vector4::Zero;
|
|
|
|
m_stStatic.Color = Vector4::One;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbStatic.updateData(m_stStatic, m_context.Get());
|
2020-07-23 21:40:07 +02:00
|
|
|
m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get());
|
|
|
|
m_context->PSSetConstantBuffers(1, 1, m_cbStatic.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
m_stMisc.AlphaTest = true;
|
2020-08-09 22:15:32 +02:00
|
|
|
m_cbMisc.updateData(m_stMisc, m_context.Get());
|
2020-07-26 08:58:44 +02:00
|
|
|
m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get());
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
|
|
|
{
|
|
|
|
RendererMesh *mesh = moveableObj.ObjectMeshes[k];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
for (int j = 0; j < NUM_BUCKETS; j++)
|
|
|
|
{
|
|
|
|
RendererBucket *bucket = &mesh->Buckets[j];
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
if (bucket->Vertices.size() == 0)
|
|
|
|
continue;
|
|
|
|
|
2020-06-29 13:29:45 +02:00
|
|
|
if (j == RENDERER_BUCKET_TRANSPARENT)
|
2020-06-27 19:48:50 +02:00
|
|
|
m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF);
|
|
|
|
else
|
|
|
|
m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF);
|
|
|
|
|
|
|
|
// Draw vertices
|
2020-07-03 07:05:33 +02:00
|
|
|
m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
m_numDrawCalls++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear just the Z-buffer so we can start drawing on top of the horizon
|
2020-06-30 10:25:41 +02:00
|
|
|
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-09 15:25:56 +02:00
|
|
|
void Renderer11::Draw()
|
|
|
|
{
|
2020-07-01 08:46:07 +02:00
|
|
|
|
2020-07-03 10:09:13 +02:00
|
|
|
renderToCubemap(m_reflectionCubemap, Vector3(LaraItem->pos.xPos, LaraItem->pos.yPos - 1024, LaraItem->pos.zPos), LaraItem->roomNumber);
|
2020-08-09 15:25:56 +02:00
|
|
|
renderScene(m_backBufferRTV, m_depthStencilView, gameCamera);
|
2020-07-01 08:46:07 +02:00
|
|
|
m_context->ClearState();
|
2020-06-30 10:25:41 +02:00
|
|
|
//drawFinalPass();
|
|
|
|
m_swapChain->Present(0, 0);
|
2020-06-27 19:48:50 +02:00
|
|
|
}
|
2020-07-03 10:09:13 +02:00
|
|
|
} // namespace T5M::Renderer
|