diff --git a/TR5Main/Game/debris.cpp b/TR5Main/Game/debris.cpp index dc5f577b0..4ef48f115 100644 --- a/TR5Main/Game/debris.cpp +++ b/TR5Main/Game/debris.cpp @@ -41,8 +41,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber pos = Vector3(item->sphere.x, item->sphere.y, item->sphere.z); } fragmentsMesh = g_Renderer.getMesh(0); - for (int bucket = RENDERER_BUCKET_SOLID; bucket <= RENDERER_BUCKET_TRANSPARENT; bucket++) { - RendererBucket renderBucket = fragmentsMesh->Buckets[bucket]; + for (auto& renderBucket : fragmentsMesh->buckets) { vector* meshVertices = &renderBucket.Vertices; for (int i = 0; i < renderBucket.Indices.size(); i += 3) { @@ -52,9 +51,9 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber } if (!fragment->active) { Matrix rotationMatrix = Matrix::CreateFromYawPitchRoll(TO_RAD(yRot), 0, 0); - RendererVertex vtx0 = meshVertices->at(fragmentsMesh->Buckets[bucket].Indices[i]); - RendererVertex vtx1 = meshVertices->at(fragmentsMesh->Buckets[bucket].Indices[i + 1]); - RendererVertex vtx2 = meshVertices->at(fragmentsMesh->Buckets[bucket].Indices[i + 2]); + RendererVertex vtx0 = meshVertices->at(renderBucket.Indices[i]); + RendererVertex vtx1 = meshVertices->at(renderBucket.Indices[i + 1]); + RendererVertex vtx2 = meshVertices->at(renderBucket.Indices[i + 2]); //Take the average of all 3 local positions Vector3 localPos = (vtx0.Position + vtx1.Position + vtx2.Position) / 3; vtx0.Position -= localPos; @@ -65,7 +64,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber fragment->mesh.vertices[0] = vtx0; fragment->mesh.vertices[1] = vtx1; fragment->mesh.vertices[2] = vtx2; - fragment->mesh.bucket = (RENDERER_BUCKETS)bucket; + fragment->mesh.blendMode = renderBucket.blendMode; fragment->active = true; fragment->terminalVelocity = 1024; fragment->gravity = Vector3(0, 7, 0); diff --git a/TR5Main/Game/debris.h b/TR5Main/Game/debris.h index 5e1dabd8b..01bce2459 100644 --- a/TR5Main/Game/debris.h +++ b/TR5Main/Game/debris.h @@ -3,7 +3,7 @@ #include #include #include - +#include "RendererVertex.h" #define MAX_DEBRIS 256 typedef struct ILIGHT @@ -41,7 +41,7 @@ typedef struct ShatterImpactInfo typedef struct DebrisMesh { - RENDERER_BUCKETS bucket; + BLEND_MODES blendMode; std::array vertices; }; diff --git a/TR5Main/Game/door.cpp b/TR5Main/Game/door.cpp index 9e96cbc93..a52bafe50 100644 --- a/TR5Main/Game/door.cpp +++ b/TR5Main/Game/door.cpp @@ -759,7 +759,7 @@ void InitialiseDoor(short itemNumber) b = &g_Level.Rooms[roomNumber]; boxNumber = b->floor[(item->pos.zPos - b->z) / SECTOR(1) + dz + ((item->pos.xPos - b->x) / SECTOR(1) + dx) * b->xSize].box; } - door->d1.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; + door->d1.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; memcpy(&door->d1.data, door->d1.floor, sizeof(FLOOR_INFO)); @@ -776,7 +776,7 @@ void InitialiseDoor(short itemNumber) b = &g_Level.Rooms[roomNumber]; boxNumber = b->floor[(item->pos.zPos - b->z) / SECTOR(1) + dz + ((item->pos.xPos - b->x) / SECTOR(1) + dx) * b->xSize].box; } - door->d1flip.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; + door->d1flip.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; memcpy(&door->d1flip.data, door->d1flip.floor, sizeof(FLOOR_INFO)); } @@ -806,7 +806,7 @@ void InitialiseDoor(short itemNumber) b = &g_Level.Rooms[roomNumber]; boxNumber = b->floor[(item->pos.zPos - b->z) / SECTOR(1) + (item->pos.xPos - b->x) / SECTOR(1) * b->xSize].box; } - door->d2.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; + door->d2.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; memcpy(&door->d2.data, door->d2.floor, sizeof(FLOOR_INFO)); @@ -823,7 +823,7 @@ void InitialiseDoor(short itemNumber) b = &g_Level.Rooms[roomNumber]; boxNumber = b->floor[(item->pos.zPos - b->z) / SECTOR(1) + (item->pos.xPos - b->x) / SECTOR(1) * b->xSize].box; } - door->d2flip.block = (g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; + door->d2flip.block = (boxNumber != NO_BOX && g_Level.Boxes[boxNumber].flags & BLOCKABLE) ? boxNumber : NO_BOX; memcpy(&door->d2flip.data, door->d2flip.floor, sizeof(FLOOR_INFO)); } diff --git a/TR5Main/Renderer/ConstantBuffers/AnimatedBuffer.h b/TR5Main/Renderer/ConstantBuffers/AnimatedBuffer.h new file mode 100644 index 000000000..bff037e41 --- /dev/null +++ b/TR5Main/Renderer/ConstantBuffers/AnimatedBuffer.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +struct AnimatedFrame +{ + DirectX::SimpleMath::Vector2 topLeft; + DirectX::SimpleMath::Vector2 topRight; + DirectX::SimpleMath::Vector2 bottomRight; + DirectX::SimpleMath::Vector2 bottomLeft; +}; + +struct alignas(16) CAnimatedBuffer +{ + std::array Textures; + uint32_t NumFrames; +}; \ No newline at end of file diff --git a/TR5Main/Renderer/Render11Helper.cpp b/TR5Main/Renderer/Render11Helper.cpp index e115f57d0..01efef176 100644 --- a/TR5Main/Renderer/Render11Helper.cpp +++ b/TR5Main/Renderer/Render11Helper.cpp @@ -87,75 +87,6 @@ namespace T5M::Renderer */ } - void Renderer11::updateAnimatedTextures() - { - // Update room's animated textures - for (int i = 0; i < g_Level.Rooms.size(); i++) - { - if (m_rooms.size() <= i) - continue; - RendererRoom &const room = m_rooms[i]; - - for (int bucketIndex = 0; bucketIndex < NUM_BUCKETS; bucketIndex++) - { - RendererBucket *bucket = &room.AnimatedBuckets[bucketIndex]; - - if (bucket->Vertices.size() == 0) - continue; - - for (int p = 0; p < bucket->Polygons.size(); p++) - { - RendererPolygon *polygon = &bucket->Polygons[p]; - RendererAnimatedTextureSet &const set = m_animatedTextureSets[polygon->AnimatedSet]; - int textureIndex = -1; - for (int j = 0; j < set.NumTextures; j++) - { - if (set.Textures[j].Id == polygon->TextureId) - { - textureIndex = j; - break; - } - } - if (textureIndex == -1) - continue; - - if (textureIndex == set.NumTextures - 1) - textureIndex = 0; - else - textureIndex++; - - polygon->TextureId = set.Textures[textureIndex].Id; - - /*for (int v = 0; v < (polygon->Shape == SHAPE_RECTANGLE ? 4 : 3); v++) - { - bucket->Vertices[polygon->Indices[v]].UV.x = set.Textures[textureIndex].UV[v].x; - bucket->Vertices[polygon->Indices[v]].UV.y = set.Textures[textureIndex].UV[v].y; - }*/ - } - } - } - - // Update waterfalls textures - /*for (int i = ID_WATERFALL1; i <= ID_WATERFALLSS2; i++) { - OBJECT_INFO* obj = &Objects[i]; - - if (obj->loaded) { - RendererObject* waterfall = m_moveableObjects[i]; - - for (int m = 0; m < waterfall->ObjectMeshes.size(); m++) { - RendererMesh* mesh = waterfall->ObjectMeshes[m]; - RendererBucket* bucket = &mesh->Buckets[RENDERER_BUCKET_TRANSPARENT_DS]; - - for (int v = 0; v < bucket->Vertices.size(); v++) { - RendererVertex* vertex = &bucket->Vertices[v]; - int y = vertex->UV.y * TEXTURE_ATLAS_SIZE + 64; - y %= 128; - vertex->UV.y = (float)y / TEXTURE_ATLAS_SIZE; - } - } - } - }*/ - } void Renderer11::updateEffects(RenderView& view) { @@ -484,18 +415,13 @@ namespace T5M::Renderer for (int n = 0; n < meshPtr->buckets.size(); n++) { BUCKET *levelBucket = &meshPtr->buckets[n]; - RendererBucket *bucket; + RendererBucket bucket{}; int bucketIndex; - - if (levelBucket->blendMode != 0) - bucketIndex = RENDERER_BUCKET_TRANSPARENT; - else - bucketIndex = RENDERER_BUCKET_SOLID; - - bucket = &mesh->Buckets[bucketIndex]; - - bucket->Vertices.resize(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3); - bucket->Indices.resize(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3); + bucket.animated = levelBucket->animated; + bucket.texture = levelBucket->texture; + bucket.blendMode = static_cast(levelBucket->blendMode); + bucket.Vertices.resize(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3); + bucket.Indices.resize(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3); int lastVertex = 0; int lastIndex = 0; @@ -533,17 +459,17 @@ namespace T5M::Renderer /*if (isHairs) vertex.Bone = v;*/ - bucket->Vertices[lastVertex++] = vertex; + bucket.Vertices[lastVertex++] = vertex; } if (poly->shape == 0) { - bucket->Indices[lastIndex++] = baseVertices; - bucket->Indices[lastIndex++] = baseVertices + 1; - bucket->Indices[lastIndex++] = baseVertices + 3; - bucket->Indices[lastIndex++] = baseVertices + 2; - bucket->Indices[lastIndex++] = baseVertices + 3; - bucket->Indices[lastIndex++] = baseVertices + 1; + bucket.Indices[lastIndex++] = baseVertices; + bucket.Indices[lastIndex++] = baseVertices + 1; + bucket.Indices[lastIndex++] = baseVertices + 3; + bucket.Indices[lastIndex++] = baseVertices + 2; + bucket.Indices[lastIndex++] = baseVertices + 3; + bucket.Indices[lastIndex++] = baseVertices + 1; /*bucket->Indices.push_back(baseVertices); bucket->Indices.push_back(baseVertices + 1); @@ -554,15 +480,16 @@ namespace T5M::Renderer } else { - bucket->Indices[lastIndex++] = baseVertices; - bucket->Indices[lastIndex++] = baseVertices + 1; - bucket->Indices[lastIndex++] = baseVertices + 2; + bucket.Indices[lastIndex++] = baseVertices; + bucket.Indices[lastIndex++] = baseVertices + 1; + bucket.Indices[lastIndex++] = baseVertices + 2; /*bucket->Indices.push_back(baseVertices); bucket->Indices.push_back(baseVertices + 1); bucket->Indices.push_back(baseVertices + 2);*/ } } + mesh->buckets.push_back(bucket); } m_meshes.push_back(mesh); @@ -570,22 +497,8 @@ namespace T5M::Renderer return mesh; } - int Renderer11::getAnimatedTextureInfo(short textureId) - { - for (int i = 0; i < m_numAnimatedTextureSets; i++) - { - RendererAnimatedTextureSet &const set = m_animatedTextureSets[i]; - for (int j = 0; j < set.NumTextures; j++) - { - if (set.Textures[j].Id == textureId) - return i; - } - } - return -1; - } - bool Renderer11::isFullsScreen() -{ + bool Renderer11::isFullsScreen() { return (!Windowed); } bool Renderer11::isFading() diff --git a/TR5Main/Renderer/RenderEnums.h b/TR5Main/Renderer/RenderEnums.h index 00ce3e87e..4df3edf5d 100644 --- a/TR5Main/Renderer/RenderEnums.h +++ b/TR5Main/Renderer/RenderEnums.h @@ -42,9 +42,9 @@ typedef enum BLEND_MODES { BLENDMODE_OPAQUE = 0, BLENDMODE_ALPHATEST = 1, - BLENDMODE_ALPHABLEND = 2, + BLENDMODE_ADDITIVE = 2, BLENDMODE_SUBTRACTIVE = 3, - BLENDMODE_ADDITIVE = 4, + BLENDMODE_ALPHABLEND = 4, NUM_BLENDMODES }; diff --git a/TR5Main/Renderer/Renderer11.cpp b/TR5Main/Renderer/Renderer11.cpp index 6a69c0fc8..e76b38bbd 100644 --- a/TR5Main/Renderer/Renderer11.cpp +++ b/TR5Main/Renderer/Renderer11.cpp @@ -46,6 +46,8 @@ namespace T5M::Renderer { m_moveablesTextures.clear(); m_staticsTextures.clear(); m_spritesTextures.clear(); + m_animatedTextures.clear(); + m_animatedTextureSets.clear(); gameCamera.clear(); } diff --git a/TR5Main/Renderer/Renderer11.h b/TR5Main/Renderer/Renderer11.h index 50bdc2e45..af88d1e8f 100644 --- a/TR5Main/Renderer/Renderer11.h +++ b/TR5Main/Renderer/Renderer11.h @@ -8,8 +8,9 @@ #include "ConstantBuffers/ShadowLightBuffer.h" #include "ConstantBuffers/RoomBuffer.h" #include "ConstantBuffers/ItemBuffer.h" +#include "ConstantBuffers/AnimatedBuffer.h" #include "Frustum.h" - +#include "RendererBucket.h" #include "items.h" #include "effect.h" #include "IndexBuffer/IndexBuffer.h" @@ -59,22 +60,6 @@ namespace T5M::Renderer std::vector DisplayModes; }; - struct RendererVertex - { - DirectX::SimpleMath::Vector3 Position; - DirectX::SimpleMath::Vector3 Normal; - DirectX::SimpleMath::Vector2 UV; - DirectX::SimpleMath::Vector4 Color; - DirectX::SimpleMath::Vector3 Tangent; - DirectX::SimpleMath::Vector3 BiTangent; - float Bone; - int IndexInPoly; - int OriginalIndex; - }; - - - - struct RendererHUDBar { VertexBuffer vertexBufferBorder; @@ -102,15 +87,6 @@ namespace T5M::Renderer DirectX::SimpleMath::Vector3 Color; }; - struct RendererPolygon - { - byte Shape; - int AnimatedSet; - int TextureId; - int Distance; - int Indices[4]; - }; - struct RendererBone { DirectX::SimpleMath::Vector3 Translation; @@ -147,7 +123,6 @@ namespace T5M::Renderer struct RendererAnimatedTexture { - int Id; DirectX::SimpleMath::Vector2 UV[4]; }; @@ -157,16 +132,7 @@ namespace T5M::Renderer std::vector Textures; }; - struct RendererBucket - { - std::vector Vertices; - std::vector Indices; - std::vector Polygons; - std::vector AnimatedPolygons; - int StartVertex; - int StartIndex; - int NumTriangles; - }; + struct RendererStatic { @@ -180,8 +146,7 @@ namespace T5M::Renderer { ROOM_INFO* Room; DirectX::SimpleMath::Vector4 AmbientLight; - RendererBucket Buckets[NUM_BUCKETS]; - RendererBucket AnimatedBuckets[NUM_BUCKETS]; + std::vector buckets; std::vector Lights; std::vector Statics; bool Visited; @@ -213,8 +178,7 @@ namespace T5M::Renderer struct RendererMesh { BoundingSphere Sphere; - RendererBucket Buckets[NUM_BUCKETS]; - RendererBucket AnimatedBuckets[NUM_BUCKETS]; + std::vector buckets; std::vector Positions; }; @@ -357,6 +321,7 @@ namespace T5M::Renderer T5M::Renderer::RenderTargetCube m_reflectionCubemap; // Shaders Microsoft::WRL::ComPtr m_vsRooms; + Microsoft::WRL::ComPtr m_vsRooms_Anim; Microsoft::WRL::ComPtr m_psRooms; Microsoft::WRL::ComPtr m_vsItems; Microsoft::WRL::ComPtr m_psItems; @@ -396,6 +361,8 @@ namespace T5M::Renderer ConstantBuffer m_cbMisc; CRoomBuffer m_stRoom; ConstantBuffer m_cbRoom; + CAnimatedBuffer m_stAnimated; + ConstantBuffer m_cbAnimated; CShadowLightBuffer m_stShadowMap; ConstantBuffer m_cbShadowMap; CHUDBuffer m_stHUD; @@ -440,6 +407,7 @@ namespace T5M::Renderer std::vector m_dynamicLights; std::vector m_lines3DToDraw; std::vector m_lines2DToDraw; + std::vector m_bucketsToDraw; int m_nextSprite; RendererLine3D* m_lines3DBuffer; int m_nextLine3D; @@ -463,6 +431,7 @@ namespace T5M::Renderer bool m_firstUnderwaterDustParticles = true; std::vector m_meshes; std::vector m_roomTextures; + std::vector m_animatedTextures; std::vector m_moveablesTextures; std::vector m_staticsTextures; std::vector m_spritesTextures; @@ -495,8 +464,8 @@ namespace T5M::Renderer int m_pickupRotation; // Private functions - int getAnimatedTextureInfo(short textureId); + void drawAllStrings(); RendererMesh* getRendererMeshFromTrMesh(RendererObject* obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs); void fromTrAngle(DirectX::SimpleMath::Matrix* matrix, short* frameptr, int index); void buildHierarchy(RendererObject* obj); @@ -558,7 +527,6 @@ namespace T5M::Renderer void drawStatistics(); void drawDebris(RenderView& view,bool transparent); void drawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget); - void updateAnimatedTextures(); void createBillboardMatrix(DirectX::SimpleMath::Matrix* out, DirectX::SimpleMath::Vector3* particlePos, DirectX::SimpleMath::Vector3* cameraPos, float rotation); void drawShockwaves(RenderView& view); void drawRipples(RenderView& view); @@ -628,7 +596,6 @@ namespace T5M::Renderer void getItemAbsBonePosition(int itemNumber, DirectX::SimpleMath::Vector3* pos, int joint); int getSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, DirectX::SimpleMath::Matrix local); void getBoneMatrix(short itemNumber, int joint, DirectX::SimpleMath::Matrix* outMatrix); - void drawAllStrings(); void drawObjectOn2DPosition(short x, short y, short objectNum, short rotX, short rotY, short rotZ); RendererMesh* getMesh(int meshIndex); diff --git a/TR5Main/Renderer/Renderer11Compatibility.cpp b/TR5Main/Renderer/Renderer11Compatibility.cpp index 85afe06a3..854eefcdd 100644 --- a/TR5Main/Renderer/Renderer11Compatibility.cpp +++ b/TR5Main/Renderer/Renderer11Compatibility.cpp @@ -61,6 +61,24 @@ namespace T5M::Renderer } }*/ + std::transform(g_Level.AnimatedTexturesSequences.begin(), g_Level.AnimatedTexturesSequences.end(), std::back_inserter(m_animatedTextureSets), [](ANIMATED_TEXTURES_SEQUENCE& sequence) { + RendererAnimatedTextureSet set{}; + set.NumTextures = sequence.numFrames; + std::transform(sequence.frames.begin(), sequence.frames.end(), std::back_inserter(set.Textures), [](ANIMATED_TEXTURES_FRAME& frm) { + RendererAnimatedTexture tex{}; + tex.UV[0].x = frm.x1; + tex.UV[0].y = frm.y1; + tex.UV[1].x = frm.x2; + tex.UV[1].y = frm.y2; + tex.UV[2].x = frm.x3; + tex.UV[2].y = frm.y3; + tex.UV[3].x = frm.x4; + tex.UV[3].y = frm.y4; + return tex; + }); + return set; + }); + // Step 1: create the texture atlas /*byte* buffer = (byte*)malloc(TEXTURE_ATLAS_SIZE * TEXTURE_ATLAS_SIZE * 4); ZeroMemory(buffer, TEXTURE_ATLAS_SIZE * TEXTURE_ATLAS_SIZE * 4); @@ -118,10 +136,25 @@ namespace T5M::Renderer } else { normal = Texture2D(m_device.Get(), texture->normalMapData.data(), texture->normalMapData.size()); } - TexturePair tex =std::make_tuple(Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size()), normal); + TexturePair tex = std::make_tuple(Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size()), normal); m_roomTextures[i] = tex; } + m_animatedTextures.resize(g_Level.AnimatedTextures.size()); + for (int i = 0; i < g_Level.AnimatedTextures.size(); i++) + { + TEXTURE *texture = &g_Level.AnimatedTextures[i]; + Texture2D normal; + if (texture->normalMapData.size() < 1) { + normal = createDefaultNormalTexture(); + } + else { + normal = Texture2D(m_device.Get(), texture->normalMapData.data(), texture->normalMapData.size()); + } + TexturePair tex = std::make_tuple(Texture2D(m_device.Get(), texture->colorMapData.data(), texture->colorMapData.size()), normal); + m_animatedTextures[i] = tex; + } + m_moveablesTextures.resize(g_Level.MoveablesTextures.size()); for (int i = 0; i < g_Level.MoveablesTextures.size(); i++) { @@ -182,22 +215,16 @@ namespace T5M::Renderer int baseRoomVertex = 0; int baseRoomIndex = 0; - + for (int n = 0; n < room->buckets.size(); n++) { BUCKET* levelBucket = &room->buckets[n]; - RendererBucket* bucket; - int bucketIndex; - - if (levelBucket->blendMode != 0) - bucketIndex = RENDERER_BUCKET_TRANSPARENT; - else - bucketIndex = RENDERER_BUCKET_SOLID; - - bucket = &r->Buckets[bucketIndex]; - - bucket->Vertices.resize(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3); - bucket->Indices.resize(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3); + RendererBucket bucket{}; + bucket.animated = levelBucket->animated; + bucket.blendMode = static_cast(levelBucket->blendMode); + bucket.texture = levelBucket->texture; + bucket.Vertices.resize(levelBucket->numQuads * 4 + levelBucket->numTriangles * 3); + bucket.Indices.resize(levelBucket->numQuads * 6 + levelBucket->numTriangles * 3); int lastVertex = 0; int lastIndex = 0; @@ -210,7 +237,7 @@ namespace T5M::Renderer for (int k = 0; k < poly->indices.size(); k++) { - RendererVertex* vertex = &bucket->Vertices[lastVertex]; + RendererVertex* vertex = &bucket.Vertices[lastVertex]; int v = poly->indices[k]; vertex->Position.x = room->x + room->positions[v].x; @@ -222,7 +249,9 @@ namespace T5M::Renderer vertex->Color = Vector4(room->colors[v].x, room->colors[v].y, room->colors[v].z, 1.0f); vertex->Tangent = poly->tangents[k]; vertex->BiTangent = poly->bitangents[k]; - + vertex->IndexInPoly = k; + vertex->OriginalIndex = v; + vertex->hash = std::hash{}(vertex->Position.x) ^ std::hash{}(vertex->Position.y) ^ std::hash{}(vertex->Position.z); vertex->Bone = 0; lastVertex++; @@ -231,26 +260,28 @@ namespace T5M::Renderer if (poly->shape == 0) { - bucket->Indices[lastIndex + 0] = baseVertices + 0; //.push_back(baseVertices); - bucket->Indices[lastIndex + 1] = baseVertices + 1; //.push_back(baseVertices + 1); - bucket->Indices[lastIndex + 2] = baseVertices + 3; //.push_back(baseVertices + 3); - bucket->Indices[lastIndex + 3] = baseVertices + 2; //.push_back(baseVertices + 2); - bucket->Indices[lastIndex + 4] = baseVertices + 3; //.push_back(baseVertices + 3); - bucket->Indices[lastIndex + 5] = baseVertices + 1; //.push_back(baseVertices + 1); + bucket.Indices[lastIndex + 0] = baseVertices + 0; //.push_back(baseVertices); + bucket.Indices[lastIndex + 1] = baseVertices + 1; //.push_back(baseVertices + 1); + bucket.Indices[lastIndex + 2] = baseVertices + 3; //.push_back(baseVertices + 3); + bucket.Indices[lastIndex + 3] = baseVertices + 2; //.push_back(baseVertices + 2); + bucket.Indices[lastIndex + 4] = baseVertices + 3; //.push_back(baseVertices + 3); + bucket.Indices[lastIndex + 5] = baseVertices + 1; //.push_back(baseVertices + 1); lastIndex += 6; totalRoomsIndices += 6; } else { - bucket->Indices[lastIndex + 0] = baseVertices + 0; //.push_back(baseVertices); - bucket->Indices[lastIndex + 1] = baseVertices + 1; //.push_back(baseVertices + 1); - bucket->Indices[lastIndex + 2] = baseVertices + 2; //.push_back(baseVertices + 2); + bucket.Indices[lastIndex + 0] = baseVertices + 0; //.push_back(baseVertices); + bucket.Indices[lastIndex + 1] = baseVertices + 1; //.push_back(baseVertices + 1); + bucket.Indices[lastIndex + 2] = baseVertices + 2; //.push_back(baseVertices + 2); lastIndex += 3; totalRoomsIndices += 3; } } + r->buckets.push_back(bucket); + } if (room->lights.size() != 0) @@ -314,23 +345,19 @@ namespace T5M::Renderer { ROOM_INFO* room = &g_Level.Rooms[i]; RendererRoom* r = &m_rooms[i]; - // Merge vertices and indices in a single list - for (int j = 0; j < NUM_BUCKETS; j++) - { - RendererBucket *bucket = &r->Buckets[j]; + for (auto& bucket : r->buckets) { + bucket.StartVertex = baseRoomVertex; + bucket.StartIndex = baseRoomIndex; - bucket->StartVertex = baseRoomVertex; - bucket->StartIndex = baseRoomIndex; + for (int k = 0; k < bucket.Vertices.size(); k++) + roomVertices[baseRoomVertex + k] = bucket.Vertices[k]; - for (int k = 0; k < bucket->Vertices.size(); k++) - roomVertices[baseRoomVertex + k] = bucket->Vertices[k]; + for (int k = 0; k < bucket.Indices.size(); k++) + roomIndices[baseRoomIndex + k] = baseRoomVertex + bucket.Indices[k]; - for (int k = 0; k < bucket->Indices.size(); k++) - roomIndices[baseRoomIndex + k] = baseRoomVertex + bucket->Indices[k]; - - baseRoomVertex += bucket->Vertices.size(); - baseRoomIndex += bucket->Indices.size(); + baseRoomVertex += bucket.Vertices.size(); + baseRoomIndex += bucket.Indices.size(); } } @@ -484,9 +511,9 @@ namespace T5M::Renderer BonesToCheck[0] = jointBone->Parent->Index; BonesToCheck[1] = j; - for (int b1 = 0; b1 < NUM_BUCKETS; b1++) + for (int b1 = 0; b1 < jointMesh->buckets.size(); b1++) { - RendererBucket *jointBucket = &jointMesh->Buckets[b1]; + RendererBucket *jointBucket = &jointMesh->buckets[b1]; for (int v1 = 0; v1 < jointBucket->Vertices.size(); v1++) { @@ -499,9 +526,9 @@ namespace T5M::Renderer RendererMesh *skinMesh = objSkin.ObjectMeshes[BonesToCheck[k]]; RendererBone *skinBone = objSkin.LinearizedBones[BonesToCheck[k]]; - for (int b2 = 0; b2 < NUM_BUCKETS; b2++) + for (int b2 = 0; b2 < skinMesh->buckets.size(); b2++) { - RendererBucket *skinBucket = &skinMesh->Buckets[b2]; + RendererBucket *skinBucket = &skinMesh->buckets[b2]; for (int v2 = 0; v2 < skinBucket->Vertices.size(); v2++) { RendererVertex *skinVertex = &skinBucket->Vertices[v2]; @@ -546,9 +573,9 @@ namespace T5M::Renderer RendererMesh* currentMesh = moveable.ObjectMeshes[j]; RendererBone* currentBone = moveable.LinearizedBones[j]; - for (int b1 = 0; b1 < NUM_BUCKETS; b1++) + for (int b1 = 0; b1 < currentMesh->buckets.size(); b1++) { - RendererBucket* currentBucket = ¤tMesh->Buckets[b1]; + RendererBucket* currentBucket = ¤tMesh->buckets[b1]; for (int v1 = 0; v1 < currentBucket->Vertices.size(); v1++) { @@ -566,9 +593,9 @@ namespace T5M::Renderer if (currentVertex->OriginalIndex < 4) { - for (int b2 = 0; b2 < NUM_BUCKETS; b2++) + for (int b2 = 0; b2 < parentMesh->buckets.size(); b2++) { - RendererBucket* parentBucket = &parentMesh->Buckets[b2]; + RendererBucket* parentBucket = &parentMesh->buckets[b2]; for (int v2 = 0; v2 < parentBucket->Vertices.size(); v2++) { RendererVertex* parentVertex = &parentBucket->Vertices[v2]; @@ -589,9 +616,9 @@ namespace T5M::Renderer RendererMesh* parentMesh = moveable.ObjectMeshes[j - 1]; RendererBone* parentBone = moveable.LinearizedBones[j - 1]; - for (int b2 = 0; b2 < NUM_BUCKETS; b2++) + for (int b2 = 0; b2 < parentMesh->buckets.size(); b2++) { - RendererBucket* parentBucket = &parentMesh->Buckets[b2]; + RendererBucket* parentBucket = &parentMesh->buckets[b2]; for (int v2 = 0; v2 < parentBucket->Vertices.size(); v2++) { RendererVertex* parentVertex = &parentBucket->Vertices[v2]; @@ -627,9 +654,9 @@ namespace T5M::Renderer { RendererMesh *msh = moveable.ObjectMeshes[m]; - for (int j = 0; j < NUM_BUCKETS; j++) + for (int j = 0; j < msh->buckets.size(); j++) { - RendererBucket *bucket = &msh->Buckets[j]; + RendererBucket *bucket = &msh->buckets[j]; bucket->StartVertex = baseMoveablesVertex; bucket->StartIndex = baseMoveablesIndex; @@ -673,9 +700,9 @@ namespace T5M::Renderer // Merge vertices and indices in a single list RendererMesh *msh = staticObject.ObjectMeshes[0]; - for (int j = 0; j < NUM_BUCKETS; j++) + for (int j = 0; j < msh->buckets.size(); j++) { - RendererBucket *bucket = &msh->Buckets[j]; + RendererBucket *bucket = &msh->buckets[j]; bucket->StartVertex = baseStaticsVertex; bucket->StartIndex = baseStaticsIndex; @@ -730,7 +757,7 @@ namespace T5M::Renderer m_spriteSequences[MoveablesIds[i]] = sequence; } } - + /* for (int i = 0; i < 6; i++) { if (Objects[ID_WATERFALL1 + i].loaded) @@ -738,8 +765,8 @@ namespace T5M::Renderer // Get the first textured bucket RendererBucket *bucket = NULL; for (int j = 0; j < NUM_BUCKETS; j++) - if (m_moveableObjects[ID_WATERFALL1 + i]->ObjectMeshes[0]->Buckets[j].Polygons.size() > 0) - bucket = &m_moveableObjects[ID_WATERFALL1 + i]->ObjectMeshes[0]->Buckets[j]; + if (m_moveableObjects[ID_WATERFALL1 + i]->ObjectMeshes[0]->buckets[j].Polygons.size() > 0) + bucket = &m_moveableObjects[ID_WATERFALL1 + i]->ObjectMeshes[0]->buckets[j]; if (bucket == NULL) continue; @@ -749,7 +776,7 @@ namespace T5M::Renderer WaterfallY[i] = texture->vertices[0].y; } } - + */ return true; } } // namespace T5M::Renderer diff --git a/TR5Main/Renderer/Renderer11Draw.cpp b/TR5Main/Renderer/Renderer11Draw.cpp index 10d863e61..27928649c 100644 --- a/TR5Main/Renderer/Renderer11Draw.cpp +++ b/TR5Main/Renderer/Renderer11Draw.cpp @@ -120,22 +120,21 @@ namespace T5M::Renderer m_context->VSSetConstantBuffers(1, 1, m_cbItem.get()); m_context->PSSetConstantBuffers(1, 1, m_cbItem.get()); - for (int m = 0; m < NUM_BUCKETS; m++) + for (auto& bucket : mesh->buckets) { - RendererBucket *bucket = &mesh->Buckets[m]; - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0) continue; - if (m < 2) + if (bucket.blendMode == 0) m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); else m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); - m_stMisc.AlphaTest = (m < 2); + m_stMisc.AlphaTest = (bucket.blendMode == 0); m_cbMisc.updateData(m_stMisc, m_context.Get()); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get()); - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); } } @@ -293,15 +292,13 @@ namespace T5M::Renderer { RendererMesh *mesh = getMesh(Lara.meshPtrs[k]); - for (int j = 0; j < 2; j++) + for (auto& bucket : mesh->buckets) { - RendererBucket *bucket = &mesh->Buckets[j]; - - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0 && bucket.blendMode != 0) continue; // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } @@ -314,17 +311,15 @@ namespace T5M::Renderer { RendererMesh *mesh = laraSkinJoints.ObjectMeshes[k]; - for (int j = 0; j < 2; j++) - { - RendererBucket *bucket = &mesh->Buckets[j]; + for (auto& bucket : mesh->buckets) + { + if (bucket.Vertices.size() == 0 && bucket.blendMode != 0) + continue; - if (bucket->Vertices.size() == 0) - continue; - - // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } + // Draw vertices + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + m_numDrawCalls++; + } } } @@ -332,17 +327,15 @@ namespace T5M::Renderer { RendererMesh *mesh = laraSkin.ObjectMeshes[k]; - for (int j = 0; j < NUM_BUCKETS; j++) - { - RendererBucket *bucket = &mesh->Buckets[j]; + for (auto& bucket : mesh->buckets) + { + if (bucket.Vertices.size() == 0 && bucket.blendMode != 0) + continue; - if (bucket->Vertices.size() == 0) - continue; - - // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } + // Draw vertices + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + m_numDrawCalls++; + } } // Draw items @@ -368,17 +361,15 @@ namespace T5M::Renderer { RendererMesh *mesh = hairsObj.ObjectMeshes[k]; - for (int j = 0; j < 4; j++) - { - RendererBucket *bucket = &mesh->Buckets[j]; + for (auto& bucket : mesh->buckets) + { + if (bucket.Vertices.size() == 0 && bucket.blendMode != 0) + continue; - if (bucket->Vertices.size() == 0) - continue; - - // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } + // Draw vertices + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + m_numDrawCalls++; + } } } @@ -454,16 +445,15 @@ namespace T5M::Renderer RendererMesh *mesh = moveableObj.ObjectMeshes[0]; - for (int b = 0; b < NUM_BUCKETS; b++) - { - RendererBucket *bucket = &mesh->Buckets[b]; + for (auto& bucket : mesh->buckets) + { + if (bucket.Vertices.size() == 0 && bucket.blendMode == 0) + continue; - if (bucket->Vertices.size() == 0) - continue; - - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } + // Draw vertices + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + m_numDrawCalls++; + } } } @@ -1297,23 +1287,22 @@ namespace T5M::Renderer m_context->VSSetConstantBuffers(1, 1, m_cbItem.get()); m_context->PSSetConstantBuffers(1, 1, m_cbItem.get()); - for (int m = 0; m < NUM_BUCKETS; m++) - { - RendererBucket *bucket = &mesh->Buckets[m]; - if (bucket->Vertices.size() == 0) - continue; + for (auto& bucket : mesh->buckets) + { + if (bucket.Vertices.size() == 0) + continue; - if (m < 2) - m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); - else - m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); + if (bucket.blendMode == 0) + m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); + else + m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); - m_stMisc.AlphaTest = (m < 2); - m_cbMisc.updateData(m_stMisc, m_context.Get()); - m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get()); + m_stMisc.AlphaTest = (bucket.blendMode == 0); + m_cbMisc.updateData(m_stMisc, m_context.Get()); + m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get()); - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - } + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + } } short inventoryItem = ring->objects[objectIndex].inventoryObject; @@ -2130,8 +2119,8 @@ namespace T5M::Renderer }*/ } - void Renderer11::drawRats(RenderView& view) -{ + void Renderer11::drawRats(RenderView& view) { + /* UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -2177,11 +2166,11 @@ namespace T5M::Renderer } } } - + */ } - void Renderer11::drawBats(RenderView& view) -{ + void Renderer11::drawBats(RenderView& view) { + /* UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -2227,11 +2216,11 @@ namespace T5M::Renderer } } } - + */ } - void Renderer11::drawLittleBeetles(RenderView& view) -{ + void Renderer11::drawLittleBeetles(RenderView& view) { + /* UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -2277,11 +2266,12 @@ namespace T5M::Renderer } } } + */ } - void Renderer11::drawLines3D(RenderView& view) -{ + void Renderer11::drawLines3D(RenderView& view) { + m_context->RSSetState(m_states->CullNone()); m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); m_context->OMSetDepthStencilState(m_states->DepthRead(), 0); @@ -2476,10 +2466,6 @@ namespace T5M::Renderer m_items[Lara.itemNumber].Item = LaraItem; collectLightsForItem(LaraItem->roomNumber, &m_items[Lara.itemNumber], view); - // 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(time2 - time1)).count() / 1000000; time1 = time2; @@ -2525,7 +2511,7 @@ namespace T5M::Renderer drawLittleBeetles(view); // Transparent geometry - m_context->OMSetBlendState(m_states->NonPremultiplied(), NULL, 0xFFFFFFFF); + m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); m_context->OMSetDepthStencilState(m_states->DepthRead(), 0); drawRooms(true, false, view); @@ -2554,7 +2540,7 @@ namespace T5M::Renderer drawBubbles(view); drawDrips(view); drawRipples(view); - drawUnderwaterDust(view); + //drawUnderwaterDust(view); drawSplahes(view); drawShockwaves(view); drawEnergyArcs(view); @@ -2726,8 +2712,7 @@ namespace T5M::Renderer int firstBucket = (transparent ? 2 : 0); int lastBucket = (transparent ? 4 : 2); - if (m_rooms.size() <= item->Item->roomNumber) - { + if (m_rooms.size() <= item->Item->roomNumber){ return; } RendererRoom &const room = m_rooms[item->Item->roomNumber]; @@ -2752,33 +2737,31 @@ namespace T5M::Renderer m_cbMisc.updateData(m_stMisc, m_context.Get()); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get()); - for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++) - { + for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++) { if (!(item->Item->meshBits & (1 << k))) continue; RendererMesh *mesh; - if (obj->meshSwapSlot != -1 && ((item->Item->swapMeshFlags >> k) & 1)) - { + if (obj->meshSwapSlot != -1 && ((item->Item->swapMeshFlags >> k) & 1)) { RendererObject &swapMeshObj = *m_moveableObjects[obj->meshSwapSlot]; mesh = swapMeshObj.ObjectMeshes[k]; } - else - { + else { mesh = moveableObj.ObjectMeshes[k]; } - for (int j = firstBucket; j < lastBucket; j++) - { - RendererBucket *bucket = &mesh->Buckets[j]; + for (auto& bucket : mesh->buckets) { + if (animated) { + if (!bucket.animated) + continue; + } + if (bucket.Vertices.size() == 0) + continue; + if (transparent && bucket.blendMode == 0) + continue; - if (bucket->Vertices.size() == 0) - continue; - - // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + } } } @@ -2895,17 +2878,15 @@ namespace T5M::Renderer m_cbStatic.updateData(m_stStatic, m_context.Get()); m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get()); - for (int j = firstBucket; j < lastBucket; j++) - { - RendererBucket *bucket = &mesh->Buckets[j]; + for (auto& bucket : mesh->buckets) + { + if (bucket.Vertices.size() == 0) + continue; + if (transparent && bucket.blendMode == 0) + continue; - if (bucket->Vertices.size() == 0) - continue; - - // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + } } } } @@ -2914,26 +2895,26 @@ namespace T5M::Renderer { UINT stride = sizeof(RendererVertex); UINT offset = 0; - - int firstBucket = (transparent ? 1 : 0); - int lastBucket = (transparent ? 2 : 1); - + // Set vertex buffer + m_context->IASetVertexBuffers(0, 1, m_roomsVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); + m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + m_context->IASetInputLayout(m_inputLayout.Get()); + m_context->IASetIndexBuffer(m_roomsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); + // Set shaders if (!animated) { - // Set vertex buffer - m_context->IASetVertexBuffers(0, 1, m_roomsVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); - m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - m_context->IASetInputLayout(m_inputLayout.Get()); - m_context->IASetIndexBuffer(m_roomsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - } + m_context->VSSetShader(m_vsRooms.Get(), nullptr, 0); + } + else { + m_context->VSSetConstantBuffers(6, 1, m_cbAnimated.get()); + m_context->VSSetShader(m_vsRooms_Anim.Get(), nullptr, 0); + } + - // Set shaders - m_context->VSSetShader(m_vsRooms.Get(), NULL, 0); m_context->PSSetShader(m_psRooms.Get(), NULL, 0); // Set texture - 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()); + ID3D11SamplerState *sampler = m_states->AnisotropicWrap(); m_context->PSSetSamplers(0, 1, &sampler); m_context->PSSetShaderResources(1, 1, m_caustics[m_currentCausticsFrame / 2].ShaderResourceView.GetAddressOf()); @@ -2955,9 +2936,6 @@ namespace T5M::Renderer m_cbShadowMap.updateData(m_stShadowMap, m_context.Get()); m_context->VSSetConstantBuffers(4, 1, m_cbShadowMap.get()); m_context->PSSetConstantBuffers(4, 1, m_cbShadowMap.get()); - - if (animated) - m_primitiveBatch->Begin(); for (int i = 0; i < view.roomsToDraw.size(); i++) { //Draw transparent back-to-front @@ -2982,45 +2960,46 @@ namespace T5M::Renderer m_cbRoom.updateData(m_stRoom, m_context.Get()); m_context->VSSetConstantBuffers(5, 1, m_cbRoom.get()); m_context->PSSetConstantBuffers(5, 1, m_cbRoom.get()); - for (int j = firstBucket; j < lastBucket; j++) + for (auto& bucket : room->buckets) { - RendererBucket *bucket; - if (!animated) - bucket = &room->Buckets[j]; - else - bucket = &room->AnimatedBuckets[j]; - - if (bucket->Vertices.size() == 0) + if (transparent) { + if (bucket.blendMode == BLEND_MODES::BLENDMODE_OPAQUE) + continue; + } + else { + if (bucket.blendMode != BLEND_MODES::BLENDMODE_OPAQUE) + continue; + } + + if (animated) { + if (!bucket.animated) + continue; + m_context->PSSetShaderResources(0, 1, (std::get<0>(m_animatedTextures[bucket.texture])).ShaderResourceView.GetAddressOf()); + m_context->PSSetShaderResources(3, 1, (std::get<1>(m_animatedTextures[bucket.texture])).ShaderResourceView.GetAddressOf()); + RendererAnimatedTextureSet& set = m_animatedTextureSets[bucket.texture]; + m_stAnimated.NumFrames = set.NumTextures; + for (unsigned char i = 0; i < set.NumTextures; i++) { + auto& tex = set.Textures[i]; + m_stAnimated.Textures[i].topLeft = set.Textures[i].UV[0]; + m_stAnimated.Textures[i].topRight = set.Textures[i].UV[1]; + m_stAnimated.Textures[i].bottomRight = set.Textures[i].UV[2]; + m_stAnimated.Textures[i].bottomLeft = set.Textures[i].UV[3]; + } + m_cbAnimated.updateData(m_stAnimated,m_context.Get()); + } + else { + if (bucket.animated) + continue; + m_context->PSSetShaderResources(0, 1, (std::get<0>(m_roomTextures[bucket.texture])).ShaderResourceView.GetAddressOf()); + m_context->PSSetShaderResources(3, 1, (std::get<1>(m_roomTextures[bucket.texture])).ShaderResourceView.GetAddressOf()); + } + if (bucket.Vertices.size() == 0) continue; - if (!animated) - { - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); - m_numDrawCalls++; - } - /*else - { - for (int k = 0; k < bucket->Polygons.size(); k++) - { - RendererPolygon *poly = &bucket->Polygons[k]; - - if (poly->Shape == SHAPE_RECTANGLE) - { - m_primitiveBatch->DrawQuad(bucket->Vertices[poly->Indices[0]], bucket->Vertices[poly->Indices[1]], - bucket->Vertices[poly->Indices[2]], bucket->Vertices[poly->Indices[3]]); - } - else - { - m_primitiveBatch->DrawTriangle(bucket->Vertices[poly->Indices[0]], bucket->Vertices[poly->Indices[1]], - bucket->Vertices[poly->Indices[2]]); - } - } - }*/ + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); + m_numDrawCalls++; } } - - if (animated) - m_primitiveBatch->End(); } void Renderer11::drawHorizonAndSky(ID3D11DepthStencilView* depthTarget) @@ -3161,24 +3140,21 @@ namespace T5M::Renderer m_cbMisc.updateData(m_stMisc, m_context.Get()); m_context->PSSetConstantBuffers(3, 1, m_cbMisc.get()); - for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++) - { + for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++) { RendererMesh *mesh = moveableObj.ObjectMeshes[k]; - for (int j = 0; j < NUM_BUCKETS; j++) - { - RendererBucket *bucket = &mesh->Buckets[j]; + for (auto& bucket: mesh->buckets) { - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0) continue; - if (j == RENDERER_BUCKET_TRANSPARENT) + if (bucket.blendMode != 0) m_context->OMSetBlendState(m_states->Additive(), NULL, 0xFFFFFFFF); else m_context->OMSetBlendState(m_states->Opaque(), NULL, 0xFFFFFFFF); // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } diff --git a/TR5Main/Renderer/Renderer11DrawEffect.cpp b/TR5Main/Renderer/Renderer11DrawEffect.cpp index e37eada0d..43875f5dc 100644 --- a/TR5Main/Renderer/Renderer11DrawEffect.cpp +++ b/TR5Main/Renderer/Renderer11DrawEffect.cpp @@ -455,10 +455,10 @@ namespace T5M::Renderer { RendererObject& flashMoveable = *m_moveableObjects[ID_GUN_FLASH]; RendererMesh* flashMesh = flashMoveable.ObjectMeshes[0]; - for (int b = 0; b < NUM_BUCKETS; b++) { - RendererBucket* flashBucket = &flashMesh->Buckets[b]; - - if (flashBucket->Vertices.size() != 0) { + for (auto& flashBucket : flashMesh->buckets) { + if (flashBucket.blendMode == 0) + continue; + if (flashBucket.Vertices.size() != 0) { Matrix offset = Matrix::CreateTranslation(0, length, zOffset); Matrix rotation2 = Matrix::CreateRotationX(TO_RAD(rotationX)); @@ -471,7 +471,7 @@ namespace T5M::Renderer { m_cbItem.updateData(m_stItem, m_context.Get()); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get()); - m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0); + m_context->DrawIndexed(flashBucket.Indices.size(), flashBucket.StartIndex, 0); m_numDrawCalls++; } @@ -484,7 +484,7 @@ namespace T5M::Renderer { m_cbItem.updateData(m_stItem, m_context.Get()); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get()); - m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0); + m_context->DrawIndexed(flashBucket.Indices.size(), flashBucket.StartIndex, 0); m_numDrawCalls++; } } @@ -543,10 +543,10 @@ namespace T5M::Renderer { RendererMesh* flashMesh = flashMoveable.ObjectMeshes[0]; - for (int b = 0; b < NUM_BUCKETS; b++) { - RendererBucket* flashBucket = &flashMesh->Buckets[b]; - - if (flashBucket->Vertices.size() != 0) { + for (auto& flashBucket : flashMesh->buckets) { + if (flashBucket.blendMode == 0) + continue; + if (flashBucket.Vertices.size() != 0) { Matrix offset = Matrix::CreateTranslation(bites[k]->x, bites[k]->y, bites[k]->z); Matrix rotationX = Matrix::CreateRotationX(TO_RAD(49152)); Matrix rotationZ = Matrix::CreateRotationZ(TO_RAD(2 * GetRandomControl())); @@ -560,7 +560,7 @@ namespace T5M::Renderer { m_cbItem.updateData(m_stItem, m_context.Get()); m_context->VSSetConstantBuffers(1, 1, m_cbItem.get()); - m_context->DrawIndexed(flashBucket->Indices.size(), flashBucket->StartIndex, 0); + m_context->DrawIndexed(flashBucket.Indices.size(), flashBucket.StartIndex, 0); m_numDrawCalls++; } } @@ -815,14 +815,15 @@ namespace T5M::Renderer { RendererMesh* mesh = effect->Mesh; - for (int j = firstBucket; j < lastBucket; j++) { - RendererBucket* bucket = &mesh->Buckets[j]; + for (auto& bucket : mesh->buckets) { - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0) + continue; + if (transparent && bucket.blendMode == 0) continue; // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } diff --git a/TR5Main/Renderer/Renderer11Init.cpp b/TR5Main/Renderer/Renderer11Init.cpp index c7380031a..49b6ae3aa 100644 --- a/TR5Main/Renderer/Renderer11Init.cpp +++ b/TR5Main/Renderer/Renderer11Init.cpp @@ -73,21 +73,26 @@ void T5M::Renderer::Renderer11::Initialise(int w, int h, int refreshRate, bool w //_itoa(g_Configuration.shadowMapSize, shadowMapStringBuff,10); std::string shadowSizeString = std::to_string(g_Configuration.shadowMapSize); const D3D_SHADER_MACRO roomDefines[] = {"SHADOW_MAP_SIZE",shadowSizeString.c_str(),nullptr,nullptr}; - m_vsRooms = Utils::compileVertexShader(m_device.Get(),L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &roomDefines[0], blob); + const D3D_SHADER_MACRO roomDefinesAnimated[] = { "SHADOW_MAP_SIZE",shadowSizeString.c_str(),"ANIMATED" ,"",nullptr,nullptr }; + m_vsRooms = Utils::compileVertexShader(m_device.Get(),L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &roomDefines[0], blob); // Initialise input layout using the first vertex shader D3D11_INPUT_ELEMENT_DESC inputLayout[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 60, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, 72, D3D11_INPUT_PER_VERTEX_DATA, 0} + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POLYINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"DRAWINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"HASH", 0, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0} }; - Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 7, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout)); - + Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 10, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout)); + + m_vsRooms_Anim = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "VS", "vs_4_0", &roomDefinesAnimated[0], blob); m_psRooms = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Rooms.fx", "PS", "ps_4_0", &roomDefines[0], blob); m_vsItems = Utils::compileVertexShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "VS", "vs_4_0", nullptr, blob); m_psItems = Utils::compilePixelShader(m_device.Get(), L"Shaders\\DX11_Items.fx", "PS", "ps_4_0", nullptr, blob); @@ -121,6 +126,7 @@ void T5M::Renderer::Renderer11::Initialise(int w, int h, int refreshRate, bool w m_cbMisc = createConstantBuffer(); m_cbShadowMap = createConstantBuffer(); m_cbRoom = createConstantBuffer(); + m_cbAnimated = createConstantBuffer(); //Prepare HUD Constant buffer m_cbHUDBar = createConstantBuffer(); m_cbHUD = createConstantBuffer(); diff --git a/TR5Main/Renderer/Renderer11Lara.cpp b/TR5Main/Renderer/Renderer11Lara.cpp index d1cd9aa5b..5e5496a07 100644 --- a/TR5Main/Renderer/Renderer11Lara.cpp +++ b/TR5Main/Renderer/Renderer11Lara.cpp @@ -202,6 +202,9 @@ void Renderer11::updateLaraAnimations(bool force) void T5M::Renderer::Renderer11::drawLara(RenderView& view,bool transparent, bool shadowMap) { + if (transparent) + if (shadowMap) + return; // Don't draw Lara if binoculars or sniper if (BinocularRange || SpotcamOverlay || SpotcamDontDrawLara || CurrentLevel == 0) return; @@ -267,15 +270,17 @@ void T5M::Renderer::Renderer11::drawLara(RenderView& view,bool transparent, bool { RendererMesh *mesh = getMesh(Lara.meshPtrs[k]); - for (int j = firstBucket; j < lastBucket; j++) + for (auto& bucket : mesh->buckets) { - RendererBucket *bucket = &mesh->Buckets[j]; - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0) + continue; + + if (transparent && bucket.blendMode == 0) continue; // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } @@ -289,15 +294,17 @@ void T5M::Renderer::Renderer11::drawLara(RenderView& view,bool transparent, bool { RendererMesh *mesh = laraSkinJoints.ObjectMeshes[k]; - for (int j = firstBucket; j < lastBucket; j++) + for (auto& bucket : mesh->buckets) { - RendererBucket *bucket = &mesh->Buckets[j]; - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0) + continue; + + if (transparent && bucket.blendMode == 0) continue; // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } @@ -326,15 +333,17 @@ void T5M::Renderer::Renderer11::drawLara(RenderView& view,bool transparent, bool { RendererMesh* mesh = hairsObj.ObjectMeshes[k]; - for (int j = firstBucket; j < lastBucket; j++) + for (auto& bucket : mesh->buckets) { - RendererBucket* bucket = &mesh->Buckets[j]; - if (bucket->Vertices.size() == 0) + if (bucket.Vertices.size() == 0) + continue; + + if (transparent && bucket.blendMode == 0) continue; // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } @@ -353,36 +362,51 @@ void Renderer11::drawLaraHolsters(bool transparent) if(m_moveableObjects[static_cast(leftHolsterID)]){ RendererObject& holsterSkin = *m_moveableObjects[static_cast(leftHolsterID)]; RendererMesh* mesh = holsterSkin.ObjectMeshes[LM_LTHIGH]; - for(int j = firstBucket; j < lastBucket; j++){ - RendererBucket* bucket = &mesh->Buckets[j]; - if(bucket->Vertices.size() == 0) + for (auto& bucket : mesh->buckets) + { + + if (bucket.Vertices.size() == 0) continue; + + if (transparent && bucket.blendMode == 0) + continue; + // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } if(m_moveableObjects[static_cast(rightHolsterID)]){ RendererObject& holsterSkin = *m_moveableObjects[static_cast(rightHolsterID)]; RendererMesh* mesh = holsterSkin.ObjectMeshes[LM_RTHIGH]; - for(int j = firstBucket; j < lastBucket; j++){ - RendererBucket* bucket = &mesh->Buckets[j]; - if(bucket->Vertices.size() == 0) + for (auto& bucket : mesh->buckets) + { + + if (bucket.Vertices.size() == 0) continue; + + if (transparent && bucket.blendMode == 0) + continue; + // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } if(backHolsterID != HOLSTER_SLOT::Empty && m_moveableObjects[static_cast(backHolsterID)]){ RendererObject& holsterSkin = *m_moveableObjects[static_cast(backHolsterID)]; RendererMesh* mesh = holsterSkin.ObjectMeshes[LM_TORSO]; - for(int j = firstBucket; j < lastBucket; j++){ - RendererBucket* bucket = &mesh->Buckets[j]; - if(bucket->Vertices.size() == 0) + for (auto& bucket : mesh->buckets) + { + + if (bucket.Vertices.size() == 0) continue; + + if (transparent && bucket.blendMode == 0) + continue; + // Draw vertices - m_context->DrawIndexed(bucket->Indices.size(), bucket->StartIndex, 0); + m_context->DrawIndexed(bucket.Indices.size(), bucket.StartIndex, 0); m_numDrawCalls++; } } diff --git a/TR5Main/Renderer/RendererBucket.h b/TR5Main/Renderer/RendererBucket.h new file mode 100644 index 000000000..f4c53cddf --- /dev/null +++ b/TR5Main/Renderer/RendererBucket.h @@ -0,0 +1,18 @@ +#pragma once +#include "RenderEnums.h" +#include "RendererVertex.h" +#include "RendererPolygon.h" +#include +namespace T5M::Renderer { + struct RendererBucket { + size_t texture; + bool animated; + BLEND_MODES blendMode; + std::vector Vertices; + std::vector Indices; + std::vector Polygons; + int StartVertex; + int StartIndex; + + }; +} diff --git a/TR5Main/Renderer/RendererPolygon.h b/TR5Main/Renderer/RendererPolygon.h new file mode 100644 index 000000000..b46e2339d --- /dev/null +++ b/TR5Main/Renderer/RendererPolygon.h @@ -0,0 +1,10 @@ +#pragma once +namespace T5M::Renderer { + struct RendererPolygon { + unsigned char Shape; + int AnimatedSet; + int TextureId; + int Distance; + int Indices[4]; + }; +} diff --git a/TR5Main/Renderer/RendererVertex.h b/TR5Main/Renderer/RendererVertex.h new file mode 100644 index 000000000..88d95c141 --- /dev/null +++ b/TR5Main/Renderer/RendererVertex.h @@ -0,0 +1,16 @@ +#pragma once +#include +namespace T5M::Renderer { + struct RendererVertex { + DirectX::SimpleMath::Vector3 Position; + DirectX::SimpleMath::Vector3 Normal; + DirectX::SimpleMath::Vector2 UV; + DirectX::SimpleMath::Vector4 Color; + DirectX::SimpleMath::Vector3 Tangent; + DirectX::SimpleMath::Vector3 BiTangent; + float Bone; + int IndexInPoly; + int OriginalIndex; + int hash; + }; +} diff --git a/TR5Main/Shaders/DX11_Rooms.fx b/TR5Main/Shaders/DX11_Rooms.fx index 1d72c2e2e..1ee43d8fe 100644 --- a/TR5Main/Shaders/DX11_Rooms.fx +++ b/TR5Main/Shaders/DX11_Rooms.fx @@ -36,6 +36,18 @@ cbuffer RoomBuffer : register(b5) float4 AmbientColor; int water; }; +struct AnimatedFrameUV +{ + float2 topLeft; + float2 topRight; + float2 bottomRight; + float2 bottomLeft; +}; +cbuffer AnimatedBuffer : register(b6) { + AnimatedFrameUV AnimFrames[32]; + uint numAnimFrames; + +} struct PixelShaderInput { @@ -65,7 +77,7 @@ float hash(float3 n) return float((frac(sin(x)) * 7385.6093) + (frac(cos(y)) * 1934.9663) - (frac(sin(z)) * 8349.2791)); } -PixelShaderInput VS(VertexShaderInput input,uint vid : SV_VertexID) +PixelShaderInput VS(VertexShaderInput input) { PixelShaderInput output; float4 screenPos = mul(float4(input.Position, 1.0f), ViewProjection); @@ -84,12 +96,31 @@ PixelShaderInput VS(VertexShaderInput input,uint vid : SV_VertexID) output.Color = input.Color; if (water) { static const float PI = 3.14159265f; - float offset = hash(input.Position.xyz); - float wibble = sin(((((float)Frame + offset) % 64) / 64)* PI)*0.5f+0.5f; - wibble = lerp(0.4f, 1.0f, wibble); + int offset = input.Hash; + float wibble = sin((((Frame + offset) % 64) / 64.0)* PI)*0.5f+0.5f; + wibble = lerp(0.1f, 1.0f, wibble); output.Color *= wibble; } +#ifdef ANIMATED + int frame = (Frame / 2) % numAnimFrames; + switch (input.PolyIndex) { + case 0: + output.UV = AnimFrames[frame].topLeft; + break; + case 1: + output.UV = AnimFrames[frame].topRight; + break; + case 2: + output.UV = AnimFrames[frame].bottomRight; + break; + case 3: + output.UV = AnimFrames[frame].bottomLeft; + break; + } +#else output.UV = input.UV; + +#endif output.WorldPosition = input.Position.xyz; output.LightPosition = mul(float4(input.Position, 1.0f), LightViewProjection); float3x3 TBN = float3x3(input.Tangent, input.Bitangent, input.Normal); diff --git a/TR5Main/Shaders/VertexInput.hlsli b/TR5Main/Shaders/VertexInput.hlsli index 260c39a12..04fb20152 100644 --- a/TR5Main/Shaders/VertexInput.hlsli +++ b/TR5Main/Shaders/VertexInput.hlsli @@ -6,4 +6,7 @@ struct VertexShaderInput { float3 Tangent: TANGENT0; float3 Bitangent: BITANGENT0; float Bone: BLENDINDICES; + uint PolyIndex : POLYINDEX; + uint Index: DRAWINDEX; + int Hash : HASH; }; \ No newline at end of file diff --git a/TR5Main/TR5Main.vcxproj b/TR5Main/TR5Main.vcxproj index 72d2cf2c6..ae77340cd 100644 --- a/TR5Main/TR5Main.vcxproj +++ b/TR5Main/TR5Main.vcxproj @@ -15,7 +15,7 @@ {15AB0220-541C-4DA1-94EB-ED3C47E4582E} Win32Proj TR5Main - 10.0.18362.0 + 10.0.17763.0 @@ -185,6 +185,7 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts" + @@ -364,7 +365,10 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts" + + + diff --git a/TR5Main/TR5Main.vcxproj.filters b/TR5Main/TR5Main.vcxproj.filters index ec0ce2cad..384a22673 100644 --- a/TR5Main/TR5Main.vcxproj.filters +++ b/TR5Main/TR5Main.vcxproj.filters @@ -934,6 +934,18 @@ File di intestazione + File di intestazione + + + File di intestazione + + + File di intestazione + + + File di intestazione + + File di intestazione