Problems rendering stage mesh...

A place for people with an interest in developing new shmups.
Post Reply
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Problems rendering stage mesh...

Post by sniperwolf »

Okay, progress is going extremely well on the engine, I think I'm going to take a little time to optimize before I get deep into collision detection. :)

Right now, for my stage setup, I'm loading one giant mesh which contains all world objects. The individual objects are low poly [it's the series of pillars you can see in my last posted screenshot, in the vertex thread], and according to Lightwave, there are about 3000 triangles that compose the entire object. I'd say only about 100 or so are on screen at once, maybe 50 of those are visible at any given time.

They are untextured, only having a diffuse color set. I'm loading the mesh with the "Managed" mesh flag. Heck, here's my loading and rendering code:

Code: Select all

public terrainMesh(Device _device, string _meshName, float _center)
		{
			meshName = _meshName;
			device = _device;
			position = new Vector3(_center, 0.0f, 0.0f);

			ExtendedMaterial[] prefabMaterials = null;
			thisMesh = Mesh.FromFile(meshName+".x",
				MeshFlags.Managed,
				device,
				out prefabMaterials);

			if (meshTextures == null)
			{
				meshTextures  = new Texture[prefabMaterials.Length];
				meshMaterials = new Microsoft.DirectX.Direct3D.Material[prefabMaterials.Length];
				for( int i=0; i<prefabMaterials.Length; i++ )
				{
					meshMaterials[i] = prefabMaterials[i].Material3D;
            
					
					meshMaterials[i].Ambient = meshMaterials[i].Diffuse;
					
					
					if(prefabMaterials[i].TextureFilename != null)
						meshTextures[i] = TextureLoader.FromFile(device,
							prefabMaterials[i].TextureFilename);
							
				}
			}
		}

	
		public void Render()
		{	
			device.Transform.World = Matrix.Translation(position);

			for( int i=0; i<meshMaterials.Length; i++ )
			{
				device.Material = meshMaterials[i];
				device.SetTexture(0, meshTextures[i]);
				thisMesh.DrawSubset(i);
			}
		}
I also had this problem when displaying a generic, <20 polygon mesh as a backdrop. I'm seeing a drop down to 50-55 fps when I'm rendering the terrain mesh [normally it's around 130-140 if I'm not firing, and I turn off the 60fps lock].

I'm stumped!
How do I wrote code?
User avatar
landshark
Posts: 2156
Joined: Wed Jan 26, 2005 5:27 am
Location: Chicago 'Burbs

Post by landshark »

I still think you are in software mode ;)
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Post by sniperwolf »

Hmmm... here's my Init() function.

Code: Select all

public Device Init()
		{
			int adapterOrdinal = Manager.Adapters.Default.Adapter;
			Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);
			
			CreateFlags flags = CreateFlags.HardwareVertexProcessing;

			PresentParameters d3dpp = new PresentParameters();

			//d3dpp.Windowed               = false;
			d3dpp.Windowed				 = true;
			d3dpp.EnableAutoDepthStencil = true;
			d3dpp.AutoDepthStencilFormat = DepthFormat.D16;
			d3dpp.SwapEffect             = SwapEffect.Discard;
			//d3dpp.BackBufferWidth        = 1024;
			//d3dpp.BackBufferHeight       = 768;
			d3dpp.BackBufferFormat       = Format.X8R8G8B8;
			d3dpp.PresentationInterval   = PresentInterval.Immediate; 

			device = new Microsoft.DirectX.Direct3D.Device( 0, DeviceType.Hardware, parent, flags, d3dpp );
			
			device.RenderState.AlphaBlendEnable = true;
			device.RenderState.AlphaBlendOperation = BlendOperation.Subtract;
			
			device.SamplerState[0].MinFilter = TextureFilter.Linear;
			
			device.SamplerState[0].MagFilter = TextureFilter.Linear;
	
			return(device);
		}
A slightly modified generic DX initialization routine. :) Everywhere I look I see "hardware"... maybe there's a missing call somewhere or a flag not set?
How do I wrote code?
User avatar
landshark
Posts: 2156
Joined: Wed Jan 26, 2005 5:27 am
Location: Chicago 'Burbs

Post by landshark »

I haven't looked at directX code since 7sh, and it was all through C++ (IDirectDraw). This looks quite different (I've never touched .net; it's totally readable though) than what I'm used to seeing.

It *looks* like you are grabbing hardware, but again; there might be something else you are supposed to do. Do you have a clipper attached to your window? (do clippers still exist?)

Do you have a Z-buffer enabled?

Make sure that all your textures reside in vram and not system ram.

I'm not sure how terribly efficient their managed meshes are either. But 4000 polygons should be a breeze.

If you want to send the binary over my way I can give it a shot and see how it runs on my system (AMD64+GeForce6800GT)
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Post by sniperwolf »

Let me clean things up somewhat, and I'll send you the current binary, with all draw layers enabled [the background, nonmoving sprite layer and the terrain mesh]
How do I wrote code?
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Post by sniperwolf »

Oh, and as far as I know, it automatically clips inside the viewable area unless I manually disable the function. :)
How do I wrote code?
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Post by sniperwolf »

Okay, figured out after a little tinkering that it's the texture loading and processing that's killing me. The files themselves are only about 64k per texture [I think they're 128x128 each] for two textures. Turning the texture off results in 60fps, dropping down only after I've fired ~800 bullets. :D Leaving it on, however, drops me down to between 45-55fps, and they take a significant drop when I fire any amount of bullets, 800 = totally unplayable, nearly locks the engine up.

Thanks, Landshark, for your offer to be my first beta tester, but I think I might've nailed this one on my own. I'll go mess with Lightwave and my .X exporter tomorrow at work, I have a feeling that's where the problem lies. :)
How do I wrote code?
User avatar
landshark
Posts: 2156
Joined: Wed Jan 26, 2005 5:27 am
Location: Chicago 'Burbs

Post by landshark »

I completely forgot to mention one more thing.

Try to prevent texture swapping if you can. For example, draw all your bullets of one type at once, followed by the next, etc...

I'm not sure how much of a hit it is, but it will cut down a bit on the swapping.
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Post by sniperwolf »

landshark wrote:I completely forgot to mention one more thing.

Try to prevent texture swapping if you can. For example, draw all your bullets of one type at once, followed by the next, etc...

I'm not sure how much of a hit it is, but it will cut down a bit on the swapping.
Hmmm... okay. As of right now they're all using the same mesh and texture, and I'm only loading one copy of the mesh and passing it into all the functions. This was a huuuuge performance killer early on - I was creating an entirely new mesh for every bullet fired before. It runs a bit faster now. :) I'll keep this in mind for the future though, when I begin to implement other bullets and the missiles.
How do I wrote code?
User avatar
landshark
Posts: 2156
Joined: Wed Jan 26, 2005 5:27 am
Location: Chicago 'Burbs

Post by landshark »

I'm not sure how it works with managed meshes. Do they support instances?
User avatar
sniperwolf
Posts: 39
Joined: Wed Aug 10, 2005 10:44 pm
Location: Oregon

Post by sniperwolf »

landshark wrote:I'm not sure how it works with managed meshes. Do they support instances?
I'm not 100% sure, all I know is that when I create my playership class, in it's constructor I'm calling my AmmoMesh class and creating a new bullet mesh in it. For the fire() commands, I'm making a new Ammo object, and passing a reference to the bullet mesh in, so I'm only going through the load/parse textures stuff once per bullet mesh type as far as I can tell.

I'm still waaay too new in DirectX to know terribly much about it's details of operation, and lord knows MSDN is almost totally devoid of any information on managed DirectX aside from just showing class methods/properties and "Here's how to initialize a Device!". :P

I'm going to move everything over to having resource manager classes so I can better organize stuff. A MeshManager will handle my currently loaded meshes [I'll peek inside when a new mesh gets referenced, if it's been loaded I'll use the existing one, otherwise I'll load a new copy and store it in the manager's list], a TextureManager will do so for textures, I'll have one for sound effects, etc. Since 90% of the meshes in the world at any given time will be copies of other meshes [for instance, bullets, enemy meshes, etc] I think this is a logical approach.

What I'm hoping this will do is cut down on me trying to track every resource I'm using. I'll make the engine handle it automatically. This won't be until after I sort out my texture loading weirdness, and my collision detection, though.
How do I wrote code?
Post Reply