Kaynağa Gözat

implement bottom level acceleration structure generation for raytracing with directx 12

Kolja Strohm 1 ay önce
ebeveyn
işleme
8d15d68f49
17 değiştirilmiş dosya ile 337 ekleme ve 43 silme
  1. 3 3
      DX11Buffer.cpp
  2. 2 2
      DX11Buffer.h
  3. 3 2
      DX11GraphicsApi.cpp
  4. 1 1
      DX11GraphicsApi.h
  5. 154 0
      DX12BLASModel.cpp
  6. 2 1
      DX12BLASModel.h
  7. 31 3
      DX12Buffer.cpp
  8. 4 5
      DX12Buffer.h
  9. 108 9
      DX12GraphicsApi.cpp
  10. 4 2
      DX12GraphicsApi.h
  11. 1 1
      DX12Shader.cpp
  12. 4 4
      DXBuffer.cpp
  13. 5 5
      DXBuffer.h
  14. 7 0
      Model3D.cpp
  15. 3 0
      Model3D.h
  16. 3 3
      Shader.cpp
  17. 2 2
      World3D.cpp

+ 3 - 3
DX11Buffer.cpp

@@ -40,7 +40,7 @@ Framework::DX11Buffer::~DX11Buffer()
 
 // Copies the data into the buffer if it has changed
 //  zRObj: The object used to communicate with the graphics card
-void Framework::DX11Buffer::copyToGPU(int byteCount)
+void Framework::DX11Buffer::copyToGPU(__int64 byteCount)
 {
     if (!len) return;
     if (byteCount < 0) byteCount = len;
@@ -51,7 +51,7 @@ void Framework::DX11Buffer::copyToGPU(int byteCount)
     }
     if (!buffer)
     {
-        description->ByteWidth = len;
+        description->ByteWidth = (unsigned)len;
         deviceLock.lock();
         device->CreateBuffer(description, 0, &buffer);
         deviceLock.unlock();
@@ -118,7 +118,7 @@ Framework::DX11StructuredBuffer::~DX11StructuredBuffer()
 
 // Copies the data into the buffer if it has changed
 //  zRObj: The object used to communicate with the graphics card
-void Framework::DX11StructuredBuffer::copyToGPU(int byteCount)
+void Framework::DX11StructuredBuffer::copyToGPU(__int64 byteCount)
 {
     ID3D11Buffer* old = buffer;
     DX11Buffer::copyToGPU(byteCount);

+ 2 - 2
DX11Buffer.h

@@ -34,7 +34,7 @@ namespace Framework
         //! Destructor
         DLLEXPORT virtual ~DX11Buffer();
         //! Copies the data into the buffer if it has changed
-        DLLEXPORT virtual void copyToGPU(int byteCount = -1) override;
+        DLLEXPORT virtual void copyToGPU(__int64 byteCount = -1) override;
         //! Returns the buffer
         DLLEXPORT ID3D11Buffer* zBuffer() const;
     };
@@ -56,7 +56,7 @@ namespace Framework
         //! Destructor
         DLLEXPORT virtual ~DX11StructuredBuffer();
         //! Copies the data into the buffer if it has changed
-        DLLEXPORT void copyToGPU(int byteCount = -1) override;
+        DLLEXPORT void copyToGPU(__int64 byteCount = -1) override;
         //! Returns the used shader resource view
         DLLEXPORT operator ID3D11ShaderResourceView*() const;
     };

+ 3 - 2
DX11GraphicsApi.cpp

@@ -50,6 +50,7 @@ DirectX11::DirectX11()
       defaultTexture(0),
       diffuseLights(0),
       pointLights(0),
+      lastModelId(-1),
       indexBuffers(0),
       vertexBuffers(0)
 {}
@@ -631,7 +632,7 @@ void DirectX11::renderObject(Model3D* zObj)
     if (zObj->zModelData()->wasIndexBufferChanged())
     {
         this->indexBuffers[curId]->setData(
-            (void*)zObj->zModelData()->getIndexBuffer());
+            (void*)zObj->zModelData()->getIndexBuffer(), true);
         this->indexBuffers[curId]->setLength(
             zObj->zModelData()->getIndexCount() * sizeof(int));
         this->indexBuffers[curId]->copyToGPU();
@@ -640,7 +641,7 @@ void DirectX11::renderObject(Model3D* zObj)
     if (zObj->zModelData()->wasVertexBufferChanged())
     {
         this->vertexBuffers[curId]->setData(
-            (void*)zObj->zModelData()->zVertexBuffer());
+            (void*)zObj->zModelData()->zVertexBuffer(), true);
         this->vertexBuffers[curId]->setLength(
             zObj->zModelData()->getVertexCount() * sizeof(Vertex3D));
         this->vertexBuffers[curId]->copyToGPU();

+ 1 - 1
DX11GraphicsApi.h

@@ -54,7 +54,7 @@ namespace Framework
         Mat4<float> viewAndProj[2];
         Vec3<float> kamPos;
         Plane3D<float> frustrum[6];
-        int lastModelId = -1;
+        int lastModelId;
         DX11Buffer** indexBuffers;
         DX11Buffer** vertexBuffers;
 

+ 154 - 0
DX12BLASModel.cpp

@@ -0,0 +1,154 @@
+#include "DX12BLASModel.h"
+
+#include "Model3D.h"
+
+Framework::DX12BLASModel::DX12BLASModel(
+    Model3DData* zModelData, ID3D12Device5* zDevice)
+    : ReferenceCounter(),
+      zModelData(zModelData),
+      zDevice(zDevice),
+      vertexBuffers(0),
+      indexBuffers(0)
+{}
+
+Framework::DX12BLASModel::~DX12BLASModel()
+{
+    if (vertexBuffers)
+    {
+        vertexBuffers->release();
+    }
+    if (indexBuffers)
+    {
+        indexBuffers->release();
+    }
+}
+
+void Framework::DX12BLASModel::calculateBuffers()
+{
+    if (!zModelData->wasIndexBufferChanged()
+        && !zModelData->wasVertexBufferChanged())
+    {
+        return;
+    }
+    Skeleton* skeleton = zModelData->zSkeleton();
+    const Vertex3D* vertexBuffer = zModelData->zVertexBuffer();
+    const int* indexBuffer = zModelData->getIndexBuffer();
+    int vertexCount = zModelData->getVertexCount();
+    int indexCount = zModelData->getIndexCount();
+    int maxBoneId = skeleton ? skeleton->getNextBoneId() : 0;
+    int** boneIndexMapping = new int*[maxBoneId + 1];
+    memset(boneIndexMapping, 0, sizeof(int*) * (maxBoneId + 1));
+    Vec3<float>** boneVertexBuffers = new Vec3<float>*[maxBoneId + 1];
+    memset(boneVertexBuffers, 0, sizeof(Vec3<float>*) * (maxBoneId + 1));
+    int* boneVertexCount = new int[maxBoneId + 1];
+    memset(boneVertexCount, 0, sizeof(int) * (maxBoneId + 1));
+    int** boneIndexBuffers = new int*[maxBoneId + 1];
+    memset(boneIndexBuffers, 0, sizeof(int*) * (maxBoneId + 1));
+    int* boneIndexCount = new int[maxBoneId + 1];
+    memset(boneIndexCount, 0, sizeof(int) * (maxBoneId + 1));
+    for (int i = 0; i < indexCount; i += 3)
+    { // for each triangle
+        int b1 = -1;
+        int b2 = -1;
+        for (int b = 0; b < 3; b++)
+        { // for each bone of the model that is touched by the triangle
+            int bone = vertexBuffer[indexBuffer[i + b]].knochenId;
+            if (b1 != bone && b2 != bone)
+            { // check if the bone is the same as the other two bones of the
+              // triangle that were already processed
+                if (b1 < 0)
+                {
+                    b1 = bone;
+                }
+                else if (b2 < 0)
+                {
+                    b2 = bone;
+                }
+                if (!boneIndexMapping[bone])
+                {
+                    boneIndexMapping[bone] = new int[vertexCount];
+                    memset(
+                        boneIndexMapping[bone], -1, sizeof(int) * vertexCount);
+                }
+                if (!boneVertexBuffers[bone])
+                {
+                    boneVertexBuffers[bone] = new Vec3<float>[vertexCount];
+                }
+                if (!boneIndexBuffers[bone])
+                {
+                    boneIndexBuffers[bone] = new int[indexCount];
+                }
+                for (int j = 0; j < 3; j++)
+                { // add the vertecies and indices of the triangle to the
+                  // buffers of the bone
+                    if (boneIndexMapping[bone][indexBuffer[i + j]] < 0)
+                    {
+                        boneIndexMapping[bone][indexBuffer[i + j]]
+                            = boneVertexCount[bone];
+                        boneVertexBuffers[bone][boneVertexCount[bone]]
+                            = vertexBuffer[indexBuffer[i + j]].pos;
+                        boneVertexCount[bone]++;
+                    }
+                    boneIndexBuffers[bone][boneIndexCount[bone]]
+                        = boneIndexMapping[bone][indexBuffer[i + j]];
+                    boneIndexCount[bone]++;
+                }
+            }
+        }
+    }
+    zModelData->setIndexBufferChanged(0);
+    zModelData->setVertexBufferChanged(0);
+    if (!vertexBuffers)
+    {
+        vertexBuffers = new RCArray<DX12Buffer>();
+    }
+    if (!indexBuffers)
+    {
+        indexBuffers = new RCArray<DX12Buffer>();
+    }
+    vertexBuffers->clear();
+    indexBuffers->clear();
+    for (int i = 0; i <= maxBoneId; i++)
+    {
+        if (boneVertexCount[i] > 0 && boneIndexCount[i] > 0)
+        {
+            DX12Buffer* vertexBuffer
+                = new DX12Buffer(sizeof(Vec3<float>), zDevice, 0);
+            vertexBuffer->setData(boneVertexBuffers[i], true);
+            vertexBuffer->setLength(boneVertexCount[i] * sizeof(Vec3<float>));
+            vertexBuffer->copyToGPU();
+            vertexBuffers->add(vertexBuffer);
+
+            DX12Buffer* indexBuffer = new DX12Buffer(sizeof(int), zDevice, 0);
+            indexBuffer->setData(boneIndexBuffers[i], true);
+            indexBuffer->setLength(boneIndexCount[i] * sizeof(int));
+            indexBuffer->copyToGPU();
+            indexBuffers->add(indexBuffer);
+        }
+        delete[] boneIndexMapping[i];
+        delete[] boneVertexBuffers[i];
+        delete[] boneIndexBuffers[i];
+    }
+    delete[] boneIndexMapping;
+    delete[] boneVertexBuffers;
+    delete[] boneVertexCount;
+    delete[] boneIndexBuffers;
+    delete[] boneIndexCount;
+}
+
+int Framework::DX12BLASModel::getBufferCount() const
+{
+    return vertexBuffers ? vertexBuffers->getEntryCount() : 0;
+}
+
+const Framework::RCArray<Framework::DX12Buffer>*
+Framework::DX12BLASModel::zVertexBuffers() const
+{
+    return vertexBuffers;
+}
+
+const Framework::RCArray<Framework::DX12Buffer>*
+Framework::DX12BLASModel::zIndexBuffers() const
+{
+    return indexBuffers;
+}

+ 2 - 1
DX12BLASModel.h

@@ -11,11 +11,12 @@ namespace Framework
     {
     private:
         Model3DData* zModelData;
+        ID3D12Device5* zDevice;
         RCArray<DX12Buffer>* vertexBuffers;
         RCArray<DX12Buffer>* indexBuffers;
 
     public:
-        DX12BLASModel(Model3DData* zModelData);
+        DX12BLASModel(Model3DData* zModelData, ID3D12Device5* zDevice);
         ~DX12BLASModel();
 
         void calculateBuffers();

+ 31 - 3
DX12Buffer.cpp

@@ -34,15 +34,15 @@ DX12Buffer::~DX12Buffer()
 }
 
 // Copies the data into the buffer if it has changed
-void DX12Buffer::copyToGPU(int byteCount)
+void DX12Buffer::copyToGPU(__int64 byteCount)
 {
     if (!len) return;
     if (byteCount < 0) byteCount = len;
-    if (description->Width != len)
+    if (description->Width != (unsigned)len)
     {
         if (buffer) buffer->Release();
         buffer = 0;
-        description->Width = len;
+        description->Width = (unsigned)len;
     }
     if (!buffer)
     {
@@ -74,6 +74,34 @@ void DX12Buffer::copyToGPU(int byteCount)
     }
 }
 
+void Framework::DX12Buffer::createBufferWithoutData(
+    D3D12_RESOURCE_STATES states)
+{
+    if (!len) return;
+    if (description->Width != len)
+    {
+        if (buffer) buffer->Release();
+        buffer = 0;
+        description->Width = len;
+    }
+    if (!buffer)
+    {
+        D3D12_HEAP_PROPERTIES hprop;
+        hprop.Type = D3D12_HEAP_TYPE_DEFAULT;
+        hprop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+        hprop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+        hprop.CreationNodeMask = 0;
+        hprop.VisibleNodeMask = 0;
+        device->CreateCommittedResource(&hprop,
+            D3D12_HEAP_FLAG_NONE,
+            description,
+            states,
+            0,
+            __uuidof(ID3D12Resource),
+            (void**)&buffer);
+    }
+}
+
 // Returns the buffer
 ID3D12Resource* DX12Buffer::zBuffer() const
 {

+ 4 - 5
DX12Buffer.h

@@ -1,9 +1,7 @@
 #pragma once
-#include "DXBuffer.h"
+#include <d3d12.h>
 
-struct ID3D12Resource;
-struct ID3D12Device5;
-struct D3D12_RESOURCE_DESC;
+#include "DXBuffer.h"
 
 namespace Framework
 {
@@ -22,7 +20,8 @@ namespace Framework
         //! Destructor
         DLLEXPORT virtual ~DX12Buffer();
         //! Copies the data into the buffer if it has changed
-        DLLEXPORT virtual void copyToGPU(int byteCount = -1) override;
+        DLLEXPORT virtual void copyToGPU(__int64 byteCount = -1) override;
+        DLLEXPORT void createBufferWithoutData(D3D12_RESOURCE_STATES states);
         //! Returns the buffer
         DLLEXPORT ID3D12Resource* zBuffer() const;
     };

+ 108 - 9
DX12GraphicsApi.cpp

@@ -52,7 +52,11 @@ DirectX12::DirectX12()
       uiTexture(0),
       texturRegister(new TextureList()),
       vertexShader(0),
-      pixelShader(0)
+      pixelShader(0),
+      blasModels(0),
+      blasScratchBuffer(0),
+      blasResultBuffer(0),
+      lastModelId(-1)
 {
     for (int i = 0; i < 2; i++)
         backBuffer[i] = 0;
@@ -60,6 +64,22 @@ DirectX12::DirectX12()
 
 DirectX12::~DirectX12()
 {
+    if (blasModels)
+    {
+        for (int i = 0; i <= lastModelId; i++)
+        {
+            if (blasModels[i]) blasModels[i]->release();
+        }
+        delete[] blasModels;
+    }
+    if (blasScratchBuffer)
+    {
+        blasScratchBuffer->release();
+    }
+    if (blasResultBuffer)
+    {
+        blasResultBuffer->release();
+    }
     if (directCommandQueue)
     {
         directCommandQueue->flush();
@@ -108,7 +128,7 @@ DirectX12::~DirectX12()
 void DirectX12::updateBottomLevelAccelerationStructure()
 {
     bool updateRequired = 0;
-    for (Model3DData* model : *modelList->zModels())
+    for (const Model3DData* model : *modelList->zModels())
     {
         if (model->wasIndexBufferChanged() || model->wasVertexBufferChanged())
         {
@@ -116,20 +136,94 @@ void DirectX12::updateBottomLevelAccelerationStructure()
             break;
         }
     }
-    int bufferIndex = 0;
+    int bufferCount = 0;
     if (updateRequired)
     {
-        for (Model3DData* model : *modelList->zModels())
+        for (const Model3DData* model : *modelList->zModels())
+        {
+            int id = model->getId();
+            blasModels[id]->calculateBuffers();
+            bufferCount += blasModels[id]->getBufferCount();
+        }
+        D3D12_RAYTRACING_GEOMETRY_DESC* geometryDescs
+            = new D3D12_RAYTRACING_GEOMETRY_DESC[bufferCount];
+        memset(geometryDescs,
+            0,
+            sizeof(D3D12_RAYTRACING_GEOMETRY_DESC) * bufferCount);
+        int bufferIndex = 0;
+        for (const Model3DData* model : *modelList->zModels())
         {
             int id = model->getId();
-            if (model->wasIndexBufferChanged()
-                || model->wasVertexBufferChanged())
+            for (int i = 0; i < blasModels[id]->getBufferCount()
+                            && bufferIndex < bufferCount;
+                i++)
             {
-                blasModels[id]->calculateBuffers();
+                DX12Buffer* vertexBuffer
+                    = blasModels[id]->zVertexBuffers()->z(i);
+                DX12Buffer* indexBuffer = blasModels[id]->zIndexBuffers()->z(i);
+                geometryDescs[bufferIndex].Type
+                    = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
+                geometryDescs[bufferIndex].Flags
+                    = D3D12_RAYTRACING_GEOMETRY_FLAG_NONE;
+                geometryDescs[bufferIndex].Triangles.VertexBuffer.StartAddress
+                    = vertexBuffer->zBuffer()->GetGPUVirtualAddress();
+                geometryDescs[bufferIndex].Triangles.VertexBuffer.StrideInBytes
+                    = vertexBuffer->getElementLength();
+                geometryDescs[bufferIndex].Triangles.VertexCount
+                    = (unsigned)vertexBuffer->getElementCount();
+                geometryDescs[bufferIndex].Triangles.VertexFormat
+                    = DXGI_FORMAT_R32G32B32_FLOAT;
+                geometryDescs[bufferIndex].Triangles.IndexBuffer
+                    = indexBuffer->zBuffer()->GetGPUVirtualAddress();
+                geometryDescs[bufferIndex].Triangles.IndexCount
+                    = (unsigned)indexBuffer->getElementCount();
+                geometryDescs[bufferIndex].Triangles.IndexFormat
+                    = DXGI_FORMAT_R32_UINT;
+                bufferIndex++;
             }
-            bufferIndex += blasModels[id]->getBufferCount();
         }
-        // TODO: create BLAS from calculated buffers
+        D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS prebuildDesc;
+        prebuildDesc.Type
+            = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+        prebuildDesc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+        prebuildDesc.NumDescs = bufferCount;
+        prebuildDesc.pGeometryDescs = geometryDescs;
+        prebuildDesc.Flags
+            = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
+
+        D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info = {};
+        device->GetRaytracingAccelerationStructurePrebuildInfo(
+            &prebuildDesc, &info);
+
+        blasScratchBuffer->setLength((int)info.ScratchDataSizeInBytes);
+        blasScratchBuffer->createBufferWithoutData(D3D12_RESOURCE_STATE_COMMON);
+        blasResultBuffer->setLength((int)info.ResultDataMaxSizeInBytes);
+        blasResultBuffer->createBufferWithoutData(
+            D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE);
+
+        D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc;
+        buildDesc.Inputs.Type
+            = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+        buildDesc.Inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+        buildDesc.Inputs.NumDescs = bufferCount;
+        buildDesc.Inputs.pGeometryDescs = geometryDescs;
+        buildDesc.DestAccelerationStructureData
+            = {blasResultBuffer->zBuffer()->GetGPUVirtualAddress()};
+        buildDesc.ScratchAccelerationStructureData
+            = {blasScratchBuffer->zBuffer()->GetGPUVirtualAddress()};
+        buildDesc.SourceAccelerationStructureData = 0;
+        buildDesc.Inputs.Flags
+            = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_NONE;
+
+        // Build the AS
+        directCommandQueue->getCommandList()
+            ->BuildRaytracingAccelerationStructure(&buildDesc, 0, nullptr);
+        directCommandQueue
+            ->execute(); // TODO: check if this is realy necessary
+                         // here, because maybe the command list is
+                         // executed in the render function anyway
+
+        delete[] geometryDescs;
     }
 }
 
@@ -373,6 +467,11 @@ void DirectX12::initialize(
     copyCommandQueue = new DX12CopyCommandQueue(device);
     computeCommandQueue = new DX12ComputeCommandQueue(device);
 
+    blasScratchBuffer
+        = new DX12Buffer(1, device, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+    blasResultBuffer
+        = new DX12Buffer(1, device, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
+
     IDXGIFactory5* fac5 = 0;
     factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&fac5);
     if (fac5)

+ 4 - 2
DX12GraphicsApi.h

@@ -13,13 +13,13 @@ struct IDXGISwapChain4;
 struct ID3D12DescriptorHeap;
 struct ID3D12Resource;
 struct ID3D12CommandAllocator;
-struct ID3D12GraphicsCommandList;
 struct ID3D12Fence;
 struct D3D12_VIEWPORT;
 struct D3D12_VERTEX_BUFFER_VIEW;
 struct D3D12_INDEX_BUFFER_VIEW;
 struct ID3D12RootSignature;
 struct ID3D12PipelineState;
+struct ID3D12GraphicsCommandList4;
 
 namespace Framework
 {
@@ -31,7 +31,6 @@ namespace Framework
     class DX12VertexShader;
     class DX12VertexBuffer;
     class DX12IndexBuffer;
-    class ID3D12GraphicsCommandList4;
     class DX12BLASModel;
     class TextureList;
     class TextureModel;
@@ -68,6 +67,9 @@ namespace Framework
         DX12VertexShader* vertexShader;
         DX12PixelShader* pixelShader;
         DX12BLASModel** blasModels;
+        DX12Buffer* blasScratchBuffer;
+        DX12Buffer* blasResultBuffer;
+        int lastModelId;
 
         DLLEXPORT void updateBottomLevelAccelerationStructure();
 

+ 1 - 1
DX12Shader.cpp

@@ -83,7 +83,7 @@ void DX12Shader::getViewDesc(int index, D3D12_CONSTANT_BUFFER_VIEW_DESC& view)
 {
     DX12Buffer* zB = (DX12Buffer*)constBuffers->z(index);
     if (!zB) return;
-    view.SizeInBytes = zB->getElementCount() * zB->getElementLength();
+    view.SizeInBytes = (unsigned)zB->getElementCount() * zB->getElementLength();
     view.BufferLocation = zB->zBuffer()->GetGPUVirtualAddress();
 }
 

+ 4 - 4
DXBuffer.cpp

@@ -28,7 +28,7 @@ void DXBuffer::setChanged()
 
 // Changes the length of the buffer on the next call to 'copy'
 //  laen: The length in bytes
-void DXBuffer::setLength(int len)
+void DXBuffer::setLength(__int64 len)
 {
     if (this->len != len)
     {
@@ -39,9 +39,9 @@ void DXBuffer::setLength(int len)
 
 // Sets what will be copied on the next call to 'copy'
 //  data: A pointer to the data
-void DXBuffer::setData(void* data)
+void DXBuffer::setData(void* data, bool shureChanged)
 {
-    if (this->data != data)
+    if (this->data != data || shureChanged)
     {
         this->data = data;
         changed = 1;
@@ -55,7 +55,7 @@ int DXBuffer::getElementLength() const
 }
 
 // Returns the number of elements in the buffer
-int DXBuffer::getElementCount() const
+__int64 DXBuffer::getElementCount() const
 {
     return len / elLen;
 }

+ 5 - 5
DXBuffer.h

@@ -15,7 +15,7 @@ namespace Framework
     protected:
         void* data;
         bool changed;
-        int len;
+        __int64 len;
         int elLen;
 
     public:
@@ -31,15 +31,15 @@ namespace Framework
         DLLEXPORT void setChanged();
         //! Changes the length of the buffer on the next call of 'copy'
         //! \param len The length in bytes
-        DLLEXPORT void setLength(int len);
+        DLLEXPORT void setLength(__int64 len);
         //! Sets what will be copied on the next call of 'copy'
         //! \param data A pointer to the data
-        DLLEXPORT void setData(void* data);
+        DLLEXPORT void setData(void* data, bool shureChanged);
         //! Copies the data into the buffer if it has changed
-        DLLEXPORT virtual void copyToGPU(int byteCount = -1) = 0;
+        DLLEXPORT virtual void copyToGPU(__int64 byteCount = -1) = 0;
         //! Returns the length of an element in bytes
         DLLEXPORT int getElementLength() const;
         //! Returns the number of elements in the buffer
-        DLLEXPORT int getElementCount() const;
+        DLLEXPORT __int64 getElementCount() const;
     };
 } // namespace Framework

+ 7 - 0
Model3D.cpp

@@ -611,6 +611,13 @@ Skeleton* Model3DData::copySkeleton() const
     return skelett ? skelett->copySceleton() : 0;
 }
 
+// Returns a pointer to the skeleton of the model without increasing the
+// reference counter
+Skeleton* Framework::Model3DData::zSkeleton() const
+{
+    return skelett;
+}
+
 // Returns the number of vertices
 int Model3DData::getVertexCount() const
 {

+ 3 - 0
Model3D.h

@@ -248,6 +248,9 @@ namespace Framework
         DLLEXPORT float getSpecularFactor() const;
         //! Returns a copy of the skeleton that can be used for animations
         DLLEXPORT Skeleton* copySkeleton() const;
+        //! Returns a pointer to the skeleton of the model without increasing
+        //! the reference counter
+        DLLEXPORT Skeleton* zSkeleton() const;
         //! Returns the number of vertices
         DLLEXPORT int getVertexCount() const;
         //! Returns a buffer with all vertices of the model

+ 3 - 3
Shader.cpp

@@ -42,8 +42,8 @@ bool Shader::fillConstBuffer(char* data, int index, int len)
     if (index < 0 || index > constBuffers->getLastIndex()) return 0;
     DXBuffer* zB = constBuffers->z(index);
     if (!zB) return 0;
-    if (len < 0) len = zB->getElementCount() * zB->getElementLength();
-    zB->setData(data);
+    if (len < 0) len = (int)zB->getElementCount() * zB->getElementLength();
+    zB->setData(data, true);
     zB->copyToGPU(len);
     return 1;
 }
@@ -55,7 +55,7 @@ int Shader::getConstBufferLaenge(int index) const
     if (index < 0 || index > constBuffers->getLastIndex()) return 0;
     DXBuffer* zB = constBuffers->z(index);
     if (!zB) return 0;
-    return zB->getElementCount() * zB->getElementLength();
+    return (unsigned)zB->getElementCount() * zB->getElementLength();
 }
 
 // Returns the shader type

+ 2 - 2
World3D.cpp

@@ -248,10 +248,10 @@ int Framework::World3D::getDiffuseLightCount() const
 
 void Framework::World3D::copyLight(DXBuffer* zDiffuse, DXBuffer* zPoints) const
 {
-    zDiffuse->setData(diffuseLights);
+    zDiffuse->setData(diffuseLights, true);
     zDiffuse->setLength(diffuseLightCount * (int)sizeof(DiffuseLight));
     zDiffuse->copyToGPU();
-    zPoints->setData(pointLights);
+    zPoints->setData(pointLights, true);
     zPoints->setLength(pointLightCount * (int)sizeof(PointLight));
     zPoints->copyToGPU();
 }