add MatrixState and PoseData, bottle is now independently scaled from spinnycube

This commit is contained in:
Adam Jensen 2022-06-25 00:57:39 +01:00
parent 59db53072f
commit fc4a17ba22
13 changed files with 166 additions and 16 deletions

View File

@ -24,6 +24,7 @@ target_sources(dxhr PRIVATE
PCDX11InternalResource.cpp
PCDX11LightManager.cpp
PCDX11Material.cpp
PCDX11MatrixState.cpp
PCDX11ModelDrawable.cpp
PCDX11RenderContext.cpp
PCDX11RenderDevice.cpp

View File

@ -204,8 +204,8 @@ void CommonRenderDevice::method_124() {
// TODO
}
void CommonRenderDevice::method_128() {
// TODO
void *CommonRenderDevice::linearAlloc30(uint32_t size, uint32_t requester) {
return (void*)linear30->alloc(size, requester, /*reportFailure=*/true);
}
RenderResource *CommonRenderDevice::method_140(uint32_t) {

View File

@ -125,7 +125,7 @@ public:
virtual void method_11C();
virtual void method_120();
virtual void method_124();
virtual void method_128();
virtual void *linearAlloc30(uint32_t, uint32_t); // 128
virtual IMaterial *createMaterial() = 0;
virtual TextureMap *createTexture(uint32_t) = 0;
virtual void createProceduralTexture() = 0;

25
rendering/IMatrixState.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
namespace cdc {
class IMatrixState {
public:
virtual void resize(uint32_t) = 0;
// virtual void method_04() = 0;
// virtual void method_08() = 0;
// virtual void method_0C() = 0;
// virtual void method_10() = 0;
// virtual void method_14() = 0;
// virtual void method_18() = 0;
// virtual void method_1C() = 0;
// virtual void method_20() = 0;
// virtual void method_24() = 0;
// virtual void method_28() = 0;
// virtual void method_2C() = 0;
// virtual void method_30() = 0;
// virtual inline uint8_t method_34() { return 0; };
virtual ~IMatrixState() = default; // 38
};
}

View File

@ -0,0 +1,13 @@
#include "PCDX11MatrixState.h"
#include "PCDX11RenderDevice.h"
namespace cdc {
void PCDX11MatrixState::resize(uint32_t count) {
poseData = (PoseData*)renderDevice18->linearAlloc30(
/*size=*/ 16 + 64 * count + 16 * count,
/*requester=*/ 7);
// dword10 = renderDevice18->method_3C();
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#include "IMatrixState.h"
#include "PCDX11RenderExternalResource.h"
namespace cdc {
class PCDX11RenderDevice;
struct PoseData {
uint32_t numMatrices;
uint32_t padding[3];
float data[];
inline float *getMatrix(uint32_t index) {
return &data[16 * index];
}
inline float *getVector(uint32_t index) {
return &data[16 * numMatrices + 4 * index];
}
};
class PCDX11MatrixState :
public IMatrixState,
public PCDX11RenderExternalResource
{
public:
PoseData *poseData; // C
// uint32_t dword10;
PCDX11RenderDevice *renderDevice18; // even though RenderExternalResource already has a copy
// uint32_t dword18;
public:
PCDX11MatrixState(PCDX11RenderDevice *renderDevice) :
IMatrixState(),
PCDX11RenderExternalResource(renderDevice),
poseData(nullptr),
renderDevice18(renderDevice)
{}
void resize(uint32_t) override;
};
}

View File

@ -4,6 +4,7 @@
#include "buffers/PCDX11SimpleStaticVertexBuffer.h"
#include "PCDX11LightManager.h"
#include "PCDX11Material.h"
#include "PCDX11MatrixState.h" // for PoseData
#include "PCDX11ModelDrawable.h"
#include "PCDX11RenderDevice.h"
#include "PCDX11RenderModel.h"
@ -13,16 +14,21 @@
namespace cdc {
// use of this global variable makes this class thread-unsafe
static float matrixStagingBuffer[40 * 16];
PCDX11ModelDrawable::PCDX11ModelDrawable(
PCDX11RenderModel *renderModel,
MeshSub *meshSub,
MeshTab0 *tab0,
MeshTab0Ext128 *tab0Ext128)
MeshTab0Ext128 *tab0Ext128,
PoseData *poseData)
:
renderModel(renderModel),
meshSub(meshSub),
tab0(tab0),
tab0Ext128(tab0Ext128)
tab0Ext128(tab0Ext128),
poseData(poseData)
{ // hack
word4 = 1; // use RenderModel drawers
flags34 = (tab0[0].triangleCount << 8);
@ -286,12 +292,60 @@ void PCDX11ModelDrawable::draw(
}
}
void PCDX11ModelDrawable::setMatrices(
bool PCDX11ModelDrawable::setMatrices(
PCDX11StateManager *stateManager,
PCDX11ModelDrawable *prevDrawable,
bool hasBones)
{
// TODO
MeshSub *prevMeshSub = prevDrawable ? prevDrawable->meshSub : nullptr;
PoseData *prevPoseData = prevDrawable ? prevDrawable->poseData : nullptr;
if (hasBones) {
if (meshSub != prevMeshSub || poseData != prevPoseData) {
for (uint32_t i = 0; i < meshSub->commonCb3_numMatrices; i++) {
uint32_t j = meshSub->matrixGatherOffsets[i];
float *matrix = poseData->getMatrix(j);
float *vector = poseData->getVector(j);
// transpose
matrixStagingBuffer[0] = matrix[0];
matrixStagingBuffer[1] = matrix[4];
matrixStagingBuffer[2] = matrix[8];
matrixStagingBuffer[3] = matrix[12];
matrixStagingBuffer[4] = matrix[1];
matrixStagingBuffer[5] = matrix[5];
matrixStagingBuffer[6] = matrix[9];
matrixStagingBuffer[7] = matrix[13];
matrixStagingBuffer[8] = matrix[2];
matrixStagingBuffer[9] = matrix[6];
matrixStagingBuffer[10] = matrix[10];
matrixStagingBuffer[11] = matrix[14];
// last row is different
matrixStagingBuffer[12] = vector[0];
matrixStagingBuffer[13] = vector[1];
matrixStagingBuffer[14] = vector[2];
matrixStagingBuffer[15] = vector[3];
}
auto &skinningBuffer = stateManager->accessCommonCB(3);
skinningBuffer.assignRow(0, matrixStagingBuffer, 4 * meshSub->commonCb3_numMatrices);
}
}
// ModelDrawableExt *currentExt = ext && ext->projectMatrixValid ? ext : nullptr;
// ModelDrawableExt *prevExt = prevDrawable && prevDrawable->ext && prevDrawable->ext->projectMatrixValid
// ? prevDrawable->ext : nullptr;
if (poseData != prevPoseData) { // || currentExt != prevExt) {
// stateManager->setProjectMatrix(currentExt->projectMatrix);
// TODO: don't reinterpret cast
stateManager->setWorldMatrix(*reinterpret_cast<float4x4*>(poseData->getMatrix(0)));
stateManager->updateMatrices();
return poseData != prevPoseData;
}
return false;
}
void PCDX11ModelDrawable::buildAndAssignLightBuffer(

View File

@ -8,6 +8,7 @@ class PCDX11RenderModel;
class PCDX11RenderDevice;
class PCDX11StateManager;
class PCDX11StreamDecl;
class PoseData;
struct LightReceiverData;
struct ModelDrawableExt {
@ -22,6 +23,7 @@ class PCDX11ModelDrawable : public IRenderDrawable {
MeshSub *meshSub; // 14
MeshTab0 *tab0; // 18
MeshTab0Ext128 *tab0Ext128; // 1C
PoseData *poseData; // 20
LightReceiverData *lightReceiverData; // 24
float *lightConstantBufferData; // 28
float float2C; // 2C
@ -33,7 +35,8 @@ public:
PCDX11RenderModel *renderModel,
MeshSub *meshSub,
MeshTab0 *tab0,
MeshTab0Ext128 *tab0Ext128);
MeshTab0Ext128 *tab0Ext128,
PoseData *poseData);
inline bool isUnlit() const { return (flags34 >> 0) & 1; }
inline bool getCullMode() const { return (flags34 >> 1) & 1; }
@ -59,7 +62,7 @@ public:
PCDX11StateManager *stateManager,
PCDX11StreamDecl *streamDecl,
bool renderTwice);
void setMatrices(
bool setMatrices(
PCDX11StateManager *stateManager,
PCDX11ModelDrawable *prevDrawable,
bool hasBones);

View File

@ -1,11 +1,12 @@
#include "PCDX11RenderModelInstance.h"
#include "PCDX11MatrixState.h"
#include "PCDX11ModelDrawable.h"
#include "PCDX11RenderDevice.h"
// #include <cstdio>
namespace cdc {
void PCDX11RenderModelInstance::recordDrawables() {
void PCDX11RenderModelInstance::recordDrawables(IMatrixState *matrixState) {
// TODO
uint32_t baseMask = this->baseMask;
if (baseMask == 0)
@ -13,6 +14,7 @@ void PCDX11RenderModelInstance::recordDrawables() {
bool addToNextScene = false;
Mesh *mesh = getRenderModel()->getMesh();
uint32_t tab0index = 0;
PoseData *poseData = static_cast<PCDX11MatrixState*>(matrixState)->poseData;
for (uint32_t i=0; i<mesh->meshCount; i++) {
MeshSub *sub = &mesh->meshTable[i];
for (uint32_t j=0; j<mesh->table0Count; j++, tab0index++) {
@ -26,7 +28,8 @@ void PCDX11RenderModelInstance::recordDrawables() {
getRenderModel(),
sub,
tab0,
tab0ext128);
tab0ext128,
poseData);
renderDevice->recordDrawable(drawable, mask, addToNextScene);
}
}

View File

@ -27,7 +27,7 @@ public:
void resConstruct() override { /*empty*/ };
void resMethod10() override { /*empty*/ };
void recordDrawables() override; // 84
void recordDrawables(IMatrixState*) override; // 84
private:
PCDX11RenderModel *getRenderModel() { return static_cast<PCDX11RenderModel*>(renderMesh); }

View File

@ -34,7 +34,7 @@ struct MeshSub {
uint32_t tab0EntryCount_30;
uint16_t commonCb3_numMatrices;
uint16_t word36;
uint32_t matrixGatherOffsets; // 38
uint32_t *matrixGatherOffsets; // 38
uint32_t vertices; // 3C, offset patched to pointer
// PCDX11StaticVertexBuffer *staticVertexBuffer;
PCDX11SimpleStaticVertexBuffer *staticVertexBuffer; // hack

View File

@ -3,9 +3,11 @@
namespace cdc {
class IMatrixState;
class RenderModelInstance : public RenderResource {
public:
virtual void recordDrawables() = 0; // 84
virtual void recordDrawables(IMatrixState*) = 0; // 84
};
}

View File

@ -26,6 +26,7 @@
#include "rendering/IPCDeviceManager.h"
#include "rendering/IRenderPassCallback.h"
#include "rendering/PCDX11DeviceManager.h"
#include "rendering/PCDX11MatrixState.h"
#include "rendering/PCDX11RenderContext.h"
#include "rendering/PCDX11RenderDevice.h"
#include "rendering/PCDX11RenderModel.h"
@ -543,7 +544,7 @@ int spinnyCube(HWND window,
///////////////////////////////////////////////////////////////////////////////////////////
float4x4 world = scale * rotateZ * rotateY * rotateX;
float4x4 world = rotateZ * rotateY * rotateX;
float4x4 project = { 2 * n / w, 0, 0, 0, 0, 2 * n / h, 0, 0, 0, 0, f / (f - n), 1, 0, 0, n * f / (n - f), 0 };
// Constants constants;
@ -565,12 +566,17 @@ int spinnyCube(HWND window,
scene->viewMatrix = translate;
scene->projectMatrix = project;
PCDX11MatrixState matrixState(renderDevice);
matrixState.resize(1);
auto *bottleWorldMatrix = reinterpret_cast<float4x4*>(matrixState.poseData->getMatrix(0));
*bottleWorldMatrix = scale * world;
// add drawables to the scene
float backgroundColor[4] = {0.025f, 0.025f, 0.025f, 1.0f};
renderDevice->clearRenderTarget(10, /*mask=*/ 1, 0.0f, backgroundColor, 1.0f, 0);
renderDevice->recordDrawable(&cubeDrawable, /*mask=*/ 1, /*addToParent=*/ 0);
static_cast<cdc::PCDX11RenderModelInstance*>(bottleRenderModelInstance)->baseMask = 0x1000; // normals
bottleRenderModelInstance->recordDrawables();
bottleRenderModelInstance->recordDrawables(&matrixState);
renderDevice->recordDrawable(&imGuiDrawable, /*mask=*/ 0x100, /*addToParent=*/ 0);
renderDevice->finishScene();