Sign in to follow this  

FPS Weapon

This topic is 4354 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This could be a general subject, but im searching for a precise answer in relation with DirectX. I'm currently working on a game engine and now im on the first person wepon part. You know the arm with a gun who always follow you everywhere ? So, that was hard to make it follow correctly the camera, but i finally did it. Now that this work, my problem is that the weapon get trough things. I thought that wasn't a problem since with collision the gun should never get trough walls, but to have a good size at the screen the weapon has to be big, and so the collision box could be strange. So, is there a way to say to directx to always draw the gun over the rest (but not over gui of course), or another solution ? thanks !

Share this post


Link to post
Share on other sites
It is quite easy actually.

1. Draw the scene like you used to do.
2. Turn of the zbuffer in the DirectX device by setting the zbufferenabled value to false. This makes sure that the weapon doesn't use the zbuffer so it is always rendered "on top". Don't forget to enable the zbuffer again after this step.
3. Render the overlay.

Hope this works for you!

Share this post


Link to post
Share on other sites
I tought about that. The problem is that the gun is a mesh, composed of subsets wich render sepraratly. So by desactivating z buffering i screw all. Polygons going oevr each other and all the rest you can imagine.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i haven't used direct x before, but its available in opengl, so you'll have to look for the equivalent function. what you need to do is clear the z buffer.

basic steps
Draw entire scene excluding gun and hud.
clear z buffer
draw gun
draw hud

Share this post


Link to post
Share on other sites
If you are using matrices and vectors the correct way, it should be easy to calculate the final world-space position of the gun. At that point, you can perform collision detection on it.

Since you are coding an FPS application, I assume that you are using a quaternion-based camera. Basically, this allows you to move in the direction that you are pointing.

Camera-Relevant Code:

// Update player position
playerPosition.yaw += playerPosition.yawVel;
playerPosition.pitch += playerPosition.pitchVel;

// Normalize and add
D3DXVECTOR3 cameraVel;
D3DXVec3TransformNormal( &cameraVel, &playerPosition.vel, &matOrientation );
playerPosition.pos += cameraVel;

// Use quaternions to rotate the camera and avoid gimble lock
D3DXQUATERNION quat;
D3DXQuaternionRotationYawPitchRoll( &quat, playerPosition.yaw, playerPosition.pitch, playerPosition.roll );
D3DXMatrixAffineTransformation( &matOrientation, 1.25f, NULL, &quat, &playerPosition.pos );
D3DXMatrixInverse( &matView, NULL, &matOrientation );


The following code will offset the player's position to obtain the gun's position:

/* BUILD THE GUN MATRIX */
D3DXVECTOR3 meshModify = D3DXVECTOR3( 3.0f, -1.5f, 10.5f ); // Offset from camera position
D3DXVec3TransformNormal( &meshModify, &meshModify, &matOrientation ); // Normalize
D3DXVECTOR3 meshPosition = playerPosition.pos + meshModify; // Add to player's position

// Build translation matrix
D3DXMatrixTranslation( &matMeshWorld, meshPosition.x, meshPosition.y, meshPosition.z );

// Build rotation matrix
D3DXMATRIX rotation;
D3DXMatrixRotationYawPitchRoll( &rotation, playerPosition.yaw, playerPosition.pitch, playerPosition.roll );

// Combine rotation and transformation
matMeshWorld = rotation * matMeshWorld;


You now have the final world-space position in meshPosition, and the final world-space matrix in matMeshWorld.

Share this post


Link to post
Share on other sites
Draw the scene
CLEAR the z-buffer but don't turn ZBUFFER off! and dont turn zwite-enabe off!
To draw the weapon succesfully, translate it farer (not so close) from the camera! (sorry, my english is...)
I mean your problem is:
near clip-plane here:|
|
WEAPON MESH WEAPON MESH WEAPON MESH
|
|
THIS SECTION <-- before the NearCplane. will to be drawn.

So, translate it, into the current position.
(It's able, that you have to set som things in the MatrixPerspFOV before the Weapon drawing.)

I hope it was helpful.

Share this post


Link to post
Share on other sites
I've been told before by a few graphics guys that they don't want to do the clear zbuffer then draw gun because it stalls the pipeline. Is this true? and if so does it incur a significant performance penalty? Also that it apparently doesn't work when using some types of shadowing.

Share this post


Link to post
Share on other sites
Why don't you look at how Quake 3 does it (Quake 3 was open sourced after all). It may not use DX but who cares? The concepts are still there. If you still insist on seeing DX code then check out DXQuake3. :)


-SirKnight

Share this post


Link to post
Share on other sites
Sure, but quake 3 doesn't use modern shadowing techniques. If I remember right its shadow maps or perspective shadow maps that have issue with the whole zbuffer clearing idea. I could be wrong though. And anyone know for sure if clearing the zbuff stalls the pipeline?

Share this post


Link to post
Share on other sites
To the anonymous poster and CastorX :

Ok, i will clear the z-buffer. But how do i do that in directx ? Because if i use the clear method it of course erase all. Should i present the things that are done (apart from the gun and the GUI), then clear and recall Present for the gun and the GUI ?

Share this post


Link to post
Share on other sites
Problem solve, i actually succeeded to erase the z-buffer. For those who come on this thread to have a solution, here it is :

As it has been said, we must clear the z-buffer between the scene objects rendering, and the gun and GUI rendering, so they are kind of independant. But it's important to clear only the z-buffer, because erasing the stencil buffer can cause problems and clearing the viewport, well... clear the viewport. So, in the Clear() call of IDirect3DDevice9, the target flag must be only D3DCLEAR_ZBUFFER. Here is an exemple :

First clear (with target flags like D3DCLEAR_ZBUFFER, D3DCLEAR_TARGET and D3DCLEAR_STENCIL)
Begins scene
Draw objects (like ground, characters, etc..)
D3DDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); (those parameters are for exemple sake, yours can be different, apart from the D3DCLEAR_ZBUFFER flag of course)
Draw gun and GUI
End scene
Present


Thnaks to you all for helping me, and good luck to new game programmer looking for this solution !

Share this post


Link to post
Share on other sites
If you want to avoid the clear and are willing to sacrifice a little z-buffer precision for it, you could solve this by splitting the Z-buffer into two "windows" - one large one that you use for the majority of the scene (say Z-values 0.05 through 1.0) and one small one that you use just for the gun (say 0.0 through 0.05). You can set these windows up using the MinZ/MaxZ parameters on the viewport.

However, because you're using a reduced Z-buffer range and thus reduced precision, you might see Z-fighting issues.

Share this post


Link to post
Share on other sites

This topic is 4354 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this