Mesh Rendering Stealing FPS

Started by
2 comments, last by hplus0603 18 years, 3 months ago
Hiya.. Im just rendering a simpel pice of a bar disk.... But when i render it the fps peeks down from 2500 (Nothing rendering except som UI and Text and light When i render the disk the ftp pops down to 1600 and with another one i go down to 1000.. I know it kind of hi FPS.. but i mean a full 3d scen consist of many more objects then that.. The following code i use to load the Mesh from an X file I allso use D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); D3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE );

VOID Mesh::CreateFromFile(LPCTSTR Name, LPCTSTR FileName)
{
	LPD3DXBUFFER D3DXMtrlBuffer;

	Meshes.Name = Name;


	
	if( FAILED( D3DXLoadMeshFromX( FileName, D3DXMESH_MANAGED, 
                                   D3DDevice, NULL, 
                                   &D3DXMtrlBuffer, NULL, &Meshes.NumMaterials, 
                                   &Meshes.Mesh ) ) )
    {
        MessageBox(NULL, "Could not find tiger.x", "Meshes.exe", MB_OK);
    }


	D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)D3DXMtrlBuffer->GetBufferPointer();
    Meshes.Materials = new D3DMATERIAL9[Meshes.NumMaterials];

    Meshes.Textures  = new LPDIRECT3DTEXTURE9[Meshes.NumMaterials];

    for( DWORD i=0; i<Meshes.NumMaterials; i++ )
    {
        Meshes.Materials = d3dxMaterials.MatD3D;
        Meshes.Materials.Ambient = Meshes.Materials.Diffuse;

        Meshes.Textures = NULL;
        if( d3dxMaterials.pTextureFilename != NULL && 
            lstrlen(d3dxMaterials.pTextureFilename) > 0 )

        D3DXCreateTextureFromFile( D3DDevice, d3dxMaterials.pTextureFilename, &Meshes.Textures );
    }

	DWORD *rgdwAdjacency = NULL;
	rgdwAdjacency = new DWORD[Meshes.Mesh->GetNumFaces() * 3];

    Meshes.Mesh->GenerateAdjacency(1e-6f,rgdwAdjacency);


	Meshes.Mesh->OptimizeInplace(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, 
												rgdwAdjacency, NULL, NULL, NULL);

	
	delete []rgdwAdjacency;
	

	Meshes.SetPos = false;
	Meshes.SetRot = false;
	Meshes.SetScale = false;

	D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.PosMatrix);
	D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.RotMatrix);
	D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.ScaleMatrix);
	D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.WorldMatrix);

    D3DXMtrlBuffer->Release();
}
and i use the folloing code to render

VOID Mesh::Render()
{
	D3DXMATRIX WorldMatrix;
	D3DXMATRIX TmpMatrix;
	D3DXMATRIX TmpMatrix2;

	D3DDevice->GetTransform( D3DTS_WORLD, &WorldMatrix);
	if(Meshes.SetPos == true)
	{
		D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.PosMatrix);
		D3DXMatrixTranslation( &Meshes.PosMatrix, Meshes.Position.x, Meshes.Position.y, Meshes.Position.z);
	}

	if(Meshes.SetRot == true)
	{
		D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.RotMatrix);
		D3DXMatrixRotationYawPitchRoll( &Meshes.RotMatrix, Meshes.Rotation.x, Meshes.Rotation.y, Meshes.Rotation.z);
	}

	if(Meshes.SetScale == true)
	{
		D3DDevice->GetTransform( D3DTS_WORLD, &Meshes.ScaleMatrix);
		D3DDevice->GetTransform( D3DTS_WORLD, &TmpMatrix2);
		D3DXMatrixScaling( &Meshes.ScaleMatrix, Meshes.Scale.x, Meshes.Scale.y, Meshes.Scale.z);
		D3DXMatrixMultiply(&Meshes.ScaleMatrix, &TmpMatrix2, &Meshes.ScaleMatrix);
        
	}

	if(Meshes.SetPos == true || Meshes.SetRot == true || Meshes.SetScale == true)
	{
		D3DXMatrixMultiply(&TmpMatrix, &Meshes.RotMatrix, &Meshes.ScaleMatrix);
		D3DXMatrixMultiply(&TmpMatrix, &TmpMatrix, &Meshes.PosMatrix);
		D3DXMatrixMultiply(&Meshes.WorldMatrix, &WorldMatrix, &TmpMatrix);
		Meshes.SetScale = false;
		Meshes.SetRot = false;
		Meshes.SetPos = false;
	}

	D3DDevice->SetTransform( D3DTS_WORLD, &Meshes.WorldMatrix);

	for( DWORD i=0; i<Meshes.NumMaterials; i++ )
    {
		D3DDevice->SetMaterial( &Meshes.Materials );
		D3DDevice->SetTexture( 0, Meshes.Textures );
        
        Meshes.Mesh->DrawSubset( i );
    }

	D3DDevice->SetTransform( D3DTS_WORLD, &WorldMatrix);
}
Maybe there is a better way to position the meshes.. or is it the drawsubset that steals the fps ??
Advertisement
Hi It's Me Again :P

There's a few things i would like to comment on your code...

First, your matrices usage...
You have a class named Mesh (which i supposed implements the behaviours of a 3D Object). So this class should implement a function like GetTransformsMatrix();

For my part, if i simplify my design, i have CObject3D, CCamera, CEntity. CObject3D implement thoses 3D behaviours and it is an abstract class, GetTransformationsMatrix is defined in here). CCamera override it to implements it own GetTransformationsMatrix() since everything is inversed.

You do not need to do, and you dont want to use GetTransformMatrix...
Your object should already know its position, orientation and scaling, it's a matters of mupliying the Rotation, Scale and Translation matrices.

My render sequence ressemble to this:
// Somewhere else i set the Projection Matrix from the used viewport, the camera could also implement the projection matrixpDevice->SetTransform(D3DTS_VIEW, pCamera->GetTransformationsMatrix());// it's alot more complicated than this, but it is enought for the demonstrationforeach (Entity to draw) {  pDevice->SetTransform(D3DTS_WORLD, pEntity->GetTransformationsMatrix());  for( DWORD i=0; i<Meshes.NumMaterials; i++ )  {    D3DDevice->SetMaterial( &pEntity->Materials );    D3DDevice->SetTexture( 0, pEntity->Textures );    pEntity->DrawSubset( i );  }}



And also, i normaly use the Optimize function instead of OptimizeInPlace, which optimize a clone of the Mesh. However, this shoulnt be a problem.

I'm very curious about your framerate, looking at your renderloop, its seems not too bad. What else is running in your GameLoop?

Jonathan

[Edited by - LowRad on January 2, 2006 11:00:02 PM]
If you wanna see a system that is similar to the one i used to manage all thoses transformations and objects..

Take a look at : http://www.geometrictools.com/Books/GameEngineArchitecture/BookSample.pdf

Or SceneGraph at this link or search google:
http://www.gamedev.net/community/forums/topic.asp?topic_id=349829
Measuring FPS when the FPS is greater than ~100 or so has very little meaning. There is significant overhead in drawing the first thing you draw in a scene. There's potentially significant overhead in binding a texture for the first time during a scene. There's all kinds of interesting driver<->hardware interactions that you or I just don't know exactly what they are.

How much do you want to draw in your scene? If you want to draw 120 objects, each of which has 1200 triangles, then I suggest you create 120 spheres, each with 1200 triangles, and each with their own (dummy) texture, and draw all of them in the scene. That should tell you what FPS you'll actually get under real load (which is what matters).


If you want to look at it another way:

2000 fps means each frame takes 0.5 milliseconds.
1000 fps means each frame takes 1 millisecond.
Thus, two bar pieces took 0.5 milliseconds to render. If you render two hundred of them, and scaling is linear (which it won't be), then that will take 50 milliseconds, and you'll get 20 fps.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement