Render Loop Problems DX10, C++

Started by
9 comments, last by Martin H Hollstein 9 years, 5 months ago

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: [attachment=17700:Class Diagram.jpg]

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?

EDIT UPDATE: It seems that the issue lies within my Update method of my world, as the cube renders normally if it is static (all values only applied once). I will check this out.

EDIT UPDATE: I found the single method responsible for causing this issue. For those interested, here is my ICamera::Update(CCamera* pCamera, CMovement* pMovement) method: (Any help as to why this is happening, please let me know, I greatly appreciate this communities input.)


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);
}

The Issue has been resolved. The issues were as follows:

1) I was calculation matrices for a static camera as opossed to the dynamic camera I desired.

2) I was storing vectors that need not be stored.

Advertisement

Did you check that you're clearing the depth buffer correctly and that depth-testing/blending/culling is the same on each frame?

Try clearing all device states and resetting them at the beginning of each frame to make sure everything is the same.

There could be a ton of things wrong when you get the dreaded black screen.

Your cube may be there, but it may be

stencil culled

frustum culled

away from the camera's pos

away from the camera's view

on another render target

the same color as the render target ( ie black )

alpha tested

alpha blended

fogged ( black )

Things to try :

Render the cube, then present(), then immediately render again after changing now state, then present() again.

If it's not there, then it may be that your geometry is getting destroyed, or a constant your relied on is gone.

If it is there, try adding in parts of the state setting until it disappears again.

I recommend working "bottom-up": Use PIX or graphics debugger and make a frame capture of a failing frame and find out why nothing gets drawn. Then work your way backwards.

Also: Have you got any clue from the D3D debug layer ?

There could be a ton of things wrong when you get the dreaded black screen.

Your cube may be there, but it may be

stencil culled

frustum culled

away from the camera's pos

away from the camera's view

on another render target

the same color as the render target ( ie black )

alpha tested

alpha blended

fogged ( black )

Things to try :

Render the cube, then present(), then immediately render again after changing now state, then present() again.

If it's not there, then it may be that your geometry is getting destroyed, or a constant your relied on is gone.

If it is there, try adding in parts of the state setting until it disappears again.

Alright, let me add a little more background. This is an early alpha of my engine and therefore only supports the simplest rendering of geometry right now.

Currently I set up my device and states in the initialization of my device. So, there is no change to cullmode, alpha blending, fog, stencil.

I have dumps of each frame, one from when it was first drawn (cube there) then a few others where the cube is not drawn. I have a .txt error file and .txt log file built into my program to log every little thing that happens and the error is not reporting that there are issues with anything being created. For the "Things to try" I already did that, and nothing changes, pointers, variables, constants - everything.

I recommend working "bottom-up": Use PIX or graphics debugger and make a frame capture of a failing frame and find out why nothing gets drawn. Then work your way backwards.

Also: Have you got any clue from the D3D debug layer ?

Okay, so I run PIX and it crashes before the program can start. It fails the initialization of the Device, however, I do have it running the debug version.

Also: My D3D debug layer is not reporting any issues at all.

PIX doesn't work on Windows 8, or on Windows 7 if you installed the recent Platform Update. You can uninstall the update if you want, otherwise you have to go without PIX. The current alternatives are the Visual Studio 2012 Graphics Debugger, AMD GPU PerfStudio, Nvidia Nsight, and Intel GPA.

What compiler are you using? If it's visual studio you could use the graphical debugger and check each stage of the pipeline to see whats it trying to render. Also, have you gotten your Project to render a cube correctly yet? or is this your first try? If you already have succeeded before what features have you added after the correct renderization started to fail?

Despite I'm not really sure about this, I will guess that you are forgetting to reinitialize(casting again to identity) some matrix in your matrix calculations, making the calculations to acumulate wrong results.

My tip here is that you should never run a complex Project before testing each basic part, because if you don't, and test only when you have a lot of features on, things get complicated.

I am using VS2010 Pro, and I have done just as you said. And yes, it has rendered a cube correctly. If you read the edits, you will see what I have found.

I will see if I am missing to reset a matrix to its identity.


My tip here is that you should never run a complex Project before testing each basic part, because if you don't, and test only when you have a lot of features on, things get complicated.

I did, only after that, I decided to implement my component interface management system.

I am using VS2010 Pro, and I have done just as you said. And yes, it has rendered a cube correctly. If you read the edits, you will see what I have found.

I will see if I am missing to reset a matrix to its identity.


My tip here is that you should never run a complex Project before testing each basic part, because if you don't, and test only when you have a lot of features on, things get complicated.

I did, only after that, I decided to implement my component interface management system.

If you're sure that the camera update is causing the problem, I sugest you to check:

1- Are all Camera members initialized correctly?
2- Are you setting all the members required for the calculations correctly from outside the class?
3- If it's working before you do the calculations on the update method, how are the matrices needed for rendering calculated before you actually run the update method?

Just a side question, are you completely sure on how you calculate the câmera matrices?

That movement you're using, is it movement from the object or from the câmera? It should be from the câmera.

Also, are you setting the rotations to radians before calling MMatrixRotationRollPitchYaw()?

This topic is closed to new replies.

Advertisement