C++ DirectX10 Mesh Disappearing After One Frame, Why?

590 views Asked by At

First time poster on this site. But I have hit a serious block and am lost. If this is too much to read, the question is at the bottom. But I thought the background would help.

A little background on the project: I currently have a rendering engine set up using DirectX10. It seems that after implementing my design of component(data) pointers inside of a component manager(holds pointers to components of entities inside of world) and sending that data to an interface manager (all methods for loading, creation, updating, rendering, etc.).

Here is an image of a class diagram to make it easier to visualize: edited: (Do not have enough rep to post, so here is a link instead: https://i.stack.imgur.com/qa5yo.jpg edit: ClassDiagram

My rendering engine has a weird issue of rending a cube (parsed from a Wavefront .obj file and put into an array of custom vertices) for only one frame. After the initial presentation of the back buffer, my cube disappears.

I have gone through a lot of debugging to fix this issue, but have yielded no answers. I have files of dumps of the change in vectors for position, scale, rotation, etc. as well as the world matrix. All data in regards to the position of the object in world space and the camera position in world space maintains its integrity. I have also checked to see if there were issues with other pointers either being corrupted, being modified where they ought not to be, or deleted by accident.

Stepping through the locals over several updates and renders I find no change in Movement Components, no change in Texture components, and no change to my shader variables and pointers.

Here is the code running initially, and then the loop,

void GameWorld::Load()
{
//initialize all members here
mInterface = InterfaceManager(pDXManager);

//create entities here
mEHouse = CEntity(
    CT::MESH | CT::MOVEMENT | CT::SHADER | CT::TEXTURE,
    "House", &mCManager);

mECamera = CEntity(
    CT::CAMERA | CT::MOVEMENT | CT::LIGHT,
    "Camera", &mCManager);

//HACKS FOR TESTING ONLY
//Ideally create script to parse to create entities;
//GameWorld will have dynamic entity list;
//////////////////////////////////////////////////
tm = CMesh("../Models/Box.obj");
mCManager.mMesh[0] = &tm;

//hmmm.... how to make non-RDMS style entities...
tc = CCamera(
    XMFLOAT3(0.0f, 0.0f, 1.0f),
    XMFLOAT3(0.0f, 0.0f, 0.0f),
    XMFLOAT3(0.0f, 1.0f, 0.0f), 1);
mCManager.mCamera[0] = &tc;

tmc = CMovement(
    XMFLOAT3(0.0f, 0.0f, -10.0f),
    XMFLOAT3(0.0f, 0.0f, 0.0f),
    XMFLOAT3(0.0f, 0.0f, 0.0f));
mCManager.mMovement[1] = &tmc;
////////////////////////////////////////////////////
//only after all entities are created
mInterface.onLoad(&mCManager);
}

//core game logic goes here
void GameWorld::Update(float dt)
{
mInterface.Update(dt, &mCManager);
}

//core rendering logic goes here
void GameWorld::Render()
{
pDXManager->BeginScene();

//render calls go here
mInterface.Render(&mCManager);

//disappears after end scene
pDXManager->EndScene();
}

And here is the interface render and update methods:

void InterfaceManager::onLoad(CComponentManager* pCManager)
{
//create all
for(int i = 0; i < pCManager->mTexture.size(); ++i)
{
    mTexture2D.loadTextureFromFile(pDXManager->mD3DDevice, pCManager->mTexture[i]);
}

for(int i = 0; i < pCManager->mMesh.size(); ++i)
{
    mMesh.loadMeshFromOBJ(pCManager->mMesh[i]);
    mMesh.createMesh(pDXManager->mD3DDevice, pCManager->mMesh[i]);
}

for(int i = 0; i < pCManager->mShader.size(); ++i)
{
    mShader.Init(pDXManager->mD3DDevice, pDXManager->mhWnd, pCManager->mShader[i], pCManager->mTexture[i]);
}
//TODO: put this somewhere else to maintain structure
XMMATRIX pFOVLH = XMMatrixPerspectiveFovLH((float)D3DX_PI / 4.0f, (float)pDXManager->mWindowWidth/pDXManager->mWindowHeight, 0.1f, 1000.0f);
XMStoreFloat4x4(&pCManager->mCamera[0]->mProjectionMat, pFOVLH);

}

void InterfaceManager::Update(float dt, CComponentManager* pCManager)
{
//update input
//update ai
//update collision detection
//update physics
//update movement
for(int i = 0; i < pCManager->mMovement.size(); ++i)
{
    mMovement.transformToWorld(pCManager->mMovement[i]);
}
//update animations
//update camera
//There is only ever one active camera
//TODO: somehow set up for an activecamera variable
mCamera.Update(pCManager->mCamera[0], pCManager->mMovement[pCManager->mCamera[0]->mOwnerID]);
}

void InterfaceManager::Render(CComponentManager* pCManager)
{
for(int i = 0; i < pCManager->mMesh.size(); ++i)
{
    //render meshes
    mMesh.RenderMeshes(pDXManager->mD3DDevice, pCManager->mMesh[i]);
    //set shader variables
    mShader.setShaderMatrices(pCManager->mCamera[0], pCManager->mShader[i], pCManager->mMovement[i]);
    mShader.setShaderLight(pCManager->mLight[i], pCManager->mShader[i]);
    mShader.setShaderTexture(pCManager->mTexture[i]);
    //render shader
    mShader.RenderShader(pDXManager->mD3DDevice, pCManager->mShader[i], pCManager->mMesh[i]);
}
}

In short, my question could be this: Why is my cube only rendering for one frame, then disappearing?

UPDATE: I found the method causing the issues by isolating it. It lays within my update() method, before render(). It is when my camera is updated that it causes issues. Here is the code for that method, perhaps someone can see what I am not?

void ICamera::Update(CCamera* pCamera, CMovement* pMovement)
{
XMMATRIX rotMat = XMMatrixRotationRollPitchYaw(pMovement->mRotation.x,
    pMovement->mRotation.y,
    pMovement->mRotation.z);

XMMATRIX view = XMLoadFloat4x4(&pCamera->mViewMat);
XMVECTOR up = XMLoadFloat3(&pCamera->mUp);
XMVECTOR lookAt = XMLoadFloat3(&pCamera->mEye);
XMVECTOR pos = XMLoadFloat3(&pMovement->mPosition);

lookAt = XMVector3TransformCoord(lookAt, rotMat);
up = XMVector3TransformCoord(up, rotMat);

lookAt = pos + lookAt;

view = XMMatrixLookAtLH(pos,
    lookAt,
    up);

XMStoreFloat3(&pCamera->mEye, lookAt);
XMStoreFloat3(&pCamera->mUp, up);
XMStoreFloat4x4(&pCamera->mViewMat, view);
}
1

There are 1 answers

1
Wayne Wang On BEST ANSWER

From the camera update code, one obvious issue is the lookAt variable.

Usually lookAt variable is a "point" not a "vector" (direction), but from your code, it seems you saved it as a point, but used it as a vector. And your camera definition is also not complete, a standard camera should at least contains: position, up direction and view direction (or lookAt point). I assume you want to rotate and translate your camera in ICamera::Update function, so you rotate up and view direction, and translate the position.

I guess your CMovement will give you a new camera position and apply a rotation to the camera. Then, you can try to modify as below, (mEye and mLookAt is position, mUp is the direction)

XMVECTOR up = XMLoadFloat3(&pCamera->mUp);
XMVECTOR lookAt = XMLoadFloat3(&pCamera->mLookAt);
XMVECTOR oldPos = XMLoadFloat3(&pCamera->mEye);
XMVECTOR viewDir = lookAt - oldPos;
XMVECTOR pos = XMLoadFloat3(&pMovement->mPosition);

viewDir = XMVector3TransformCoord(viewDir, rotMat);
up = XMVector3TransformCoord(up, rotMat);

lookAt = pos + viewDir;

view = XMMatrixLookAtLH(pos,
    lookAt,
    up);

XMStoreFloat3(&pCamera->mEye, position);
XMStoreFloat3(&pCamera->mLookAt, lookAt);
XMStoreFloat3(&pCamera->mUp, up);