Drawing 3D Models over primitives in XNA

Started by
13 comments, last by LemonBiscuit 10 years, 2 months ago

Sorry about the crappy previous post.

If it suits you, another approach which may be to add to the game - fog at a reasonable distance. You can then use a smaller far plane in your projection, just beyond where fog = 1.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Advertisement

Thanks, I did like you said but still have two problems:

- My weapon is drawn as if it was "huge": it goes through terrain and traverses models.

- I put a LensFlare system, which use occlusion query, so it has to be called last: I draw everything I need to draw, then I check how much the sun is visible, and I draw the lensflares images according to this result. Problem is, it doesn't draw if I call it last.

EDIT: See my next post for revised code to show the HUD with fixed relationship to the eyepoint.

I made some assumptions and errors in my previous post. I do apologize for that.

Regarding the weapons draw - how do you set the world position of the weapon for each render frame? Do you set it according to the current eye position and direction?

Putting together some quick code, I got the following to work:

- set viewport.MaxZ = 0

- set the world transform to position the object (for instance) forward and to the right of the eye position

- set the projection to 0.2, 10.0 (near/far), other parameters otherwise the same as for the rest of the scene

- draw the object

- set viewport.MaxZ = 1

- set the projection back to (whatever you use for the rest of the scene)

- set the world transform back to (whatever you use for the rest of the scene)

- continue rendering

I found that the "hugeness" of the weapon is due to not setting the viewport parameters.

You might try that algorithm and see what happens. FYI, you needn't draw the weapons first provided you reset the viewport / projection / world transforms as indicated. However, by drawing the weapons first, as mentioned above, you'll save the overdrawing of a few pixels.

EDIT: Here's what I did. vBufAxes is just a set of axes for the world. "aspect" is the aspect ratio of the window (or backbuffer, depending on what you're drawing).


    if (vBufAxes)
    {
        if (bShowWorldAxes)
        {
            ////// testing - the origin always appears in the foreground
            D3DVIEWPORT9 vp;
            gd3dDevice->GetViewport(&vp);
            vp.MaxZ = 0;
            gd3dDevice->SetViewport(&vp);
            // world axes
            // draw them near the camera
            D3DXVECTOR3 camPos = vDxChildren[dxChildNum].dxChild->camPos;
            D3DXVECTOR3 camDir = vDxChildren[dxChildNum].dxChild->camDir;
            D3DXVECTOR3 camUp = vDxChildren[dxChildNum].dxChild->camUp;
            D3DXVECTOR3 camRight;
            D3DXVec3Normalize(&camRight, D3DXVec3Cross(&camRight, &camUp, &camDir));
            D3DXVECTOR3 axesPos = camPos + 3.0f*camDir - camUp + camRight;
            D3DXMATRIX axesWorld;
            D3DXMatrixTranslation(&axesWorld, axesPos.x, axesPos.y, axesPos.z);
            gd3dDevice->SetTransform(D3DTS_WORLD, &axesWorld);
            D3DXMATRIX tmpProj;
            D3DXMatrixPerspectiveFovLH(&tmpProj, D3DX_PI * 0.25f, aspect, 0.20f, 10.0f);
            gd3dDevice->SetTransform(D3DTS_PROJECTION, &tmpProj);
            gd3dDevice->SetFVF(COLORVERTEXFORMAT);
            gd3dDevice->SetStreamSource(0, vBufAxes, 0, sizeof(COLORVERTEX));
            gd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 24);
            vp.MaxZ = 1;
            gd3dDevice->SetViewport(&vp);
            gd3dDevice->SetTransform(D3DTS_PROJECTION, &mProj);
            gd3dDevice->SetTransform(D3DTS_WORLD, &mWorld);
        }
    }

axesHUD1.jpg

axesHUD2.jpg

NOTE: this draws the axes to reflect the orientation of the camera! I have to change the code to draw them as a fixed object. I'll be back in a while.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I have to apologize again. It's been a few years since I created a HUD. I understand it's a pain-in-the-patootie when someone posts a crappy suggestion. I appreciate your patience.

In any case, implementation depends on how you draw your weapons.

In the following code, the axes are setup at the world origin (i.e., based at (0,0,0) with axes "boxes" in each direction). I've commented out the incorrect code from the previous post.

First: set the viewport MaxZ to 0.

Second: create a view matrix positioned to view the origin-based object as you want it to appear in the HUD and set the device view matrix.

Third: set up the projection for a short field of view - i.e., near/far to something small. Ensure that the far-plane value will render all of the HUD objects.

Fourth: draw the HUD objects.

Fifth: restore the viewport and projection matrices.


    if (vBufAxes)
    {
        if (bShowWorldAxes)
        {
            ////// testing - the origin always appears in the foreground
            D3DVIEWPORT9 vp;
            gd3dDevice->GetViewport(&vp);
            vp.MaxZ = 0;
            gd3dDevice->SetViewport(&vp);
            // world axes
            D3DXMATRIX tmpView;
            D3DXVECTOR3 camPos = D3DXVECTOR3(-3,3,-10);
            D3DXVECTOR3 camDir = D3DXVECTOR3(0,0,1);
            D3DXVECTOR3 camUp = D3DXVECTOR3(0,1,0);
            D3DXVECTOR3 camAt = camPos + camDir;
            D3DXMatrixLookAtLH(&tmpView, &camPos, &camAt, &camUp);
            gd3dDevice->SetTransform(D3DTS_VIEW, &tmpView);

            //// draw them near the camera
            //D3DXVECTOR3 camPos = vDxChildren[dxChildNum].dxChild->camPos;
            //D3DXVECTOR3 camDir = vDxChildren[dxChildNum].dxChild->camDir;
            //D3DXVECTOR3 camUp = vDxChildren[dxChildNum].dxChild->camUp;
            //D3DXVECTOR3 camRight;
            //D3DXVec3Normalize(&camRight, D3DXVec3Cross(&camRight, &camUp, &camDir));
            //D3DXVECTOR3 axesPos = camPos + 3.0f*camDir - camUp + camRight;
            //D3DXMATRIX axesWorld;
            //D3DXMatrixTranslation(&axesWorld, axesPos.x, axesPos.y, axesPos.z);
            //gd3dDevice->SetTransform(D3DTS_WORLD, &axesWorld);
            D3DXMATRIX tmpProj;
            D3DXMatrixPerspectiveFovLH(&tmpProj, D3DX_PI * 0.25f, aspect, 0.20f, 20.0f);
            gd3dDevice->SetTransform(D3DTS_PROJECTION, &tmpProj);
            gd3dDevice->SetFVF(COLORVERTEXFORMAT);
            gd3dDevice->SetStreamSource(0, vBufAxes, 0, sizeof(COLORVERTEX));
            gd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 24);
            vp.MaxZ = 1;
            gd3dDevice->SetViewport(&vp);
            gd3dDevice->SetTransform(D3DTS_PROJECTION, &mProj);
            //gd3dDevice->SetTransform(D3DTS_WORLD, &mWorld);
            gd3dDevice->SetTransform(D3DTS_VIEW, &mView);
        }
    }

axesHUD_rev1.jpg

axesHUD_rev2.jpg

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thank you very much! :)

This topic is closed to new replies.

Advertisement