Using 3D primitives to display 2D bitmaps...

Started by
7 comments, last by AndrewSmart 21 years, 6 months ago
Hi all, I need to display/overlay some bitmaps onto my game screen, in order to display status info etc. The bitmaps have dynamic colouring/alpha values. I am currently using 3D primitives to do this, with the texture being set to the bitmap I want to display. I am using only a transformed and lit vertex buffer, within which I modify the x,y screen coordinates and colour of the respective vertices of the quad directly. Trouble is with this method I have to lock the buffer, modify the verts, etc etc every frame. Is there a method to do a similar thing, but using untransformed vertices, and the material colour, to achieve the same result. This would mean I wouldn''t have to lock the VBs every frame !! Thanks for any help.. Andrew
Advertisement
There are a couple of things you want to have a look at, the first is the ID3DXSprite Interface, this object is designed for just the purpose you're talking about, however the documentation for it is scant to say the least. The interface renders the texture straight out to screen space and is compatible with alpha blending and such like. It also has methods for rotating and scaling the textures.

The other way (the harder way) is a litle laborious. Firstly, why bother lighting your textures? Just deactivate the lighting renderstate (D3DRS_LIGHTING) before you render them. You may also want to deactivate fog (D3DRS_FOG) and the Z Buffer (D3DRS_ZENABLE, D3DRS_ZWRITEENABLE). Next you need to set up an orthographic projection matrix (a projection matrix that does not take into account perspective). For example:

D3DXMATRIX ortho;
D3DXMatrixOrthoLH(&ortho,100.0f,100.0f,0.0f,1.0f);

Generates an orthographic matrix with the origin on the bottom left (I think, this whole left hand/right hand thing confuses me ) You can now take a single vertex buffer holding a square with the following corner coordinates (rendered as a triangle strip):

0,0,0
1,0,0
0,1,0
1,1,0

And use that to render all of your textures, just translate and scale the VB to the screen. The following optimised function will generate the kind of world matrix you want to do this:


    inline void set2dTransformAndScale(D3DXMATRIX &in, FLOAT fPosX, FLOAT fPosY, FLOAT fScaleX, FLOAT fScaleY){   in._41=fPosX;   in._42=fPosY;   in._11=fScaleX;   int_22=fScaleY;}    


Note the 'in' matrix must either be an identity matrix or a matrix generated by the same function from an identity matrix.

Of course you may be asking 'Why Bother?' and well you might, the advantage of this approach is that the orthographic matrix's coordinate system will always be the same regardless of the screen resolution, therefore all your positioning and scaling can be kept the same if you resize the screen.

[edited by - bligblug on October 3, 2002 10:52:56 AM]
---------------------------A man is in bed with his wife smoking a cigarette. She says, "Dear, you hear all those warnings about cigarettes being bad for you health, why do you still smoke?"The man replies, "Well, I''m a programmer, we don''t pay attention to warnings, only to errors."
Thanks for that !

The longer method sounds more suitable for what I want to do. However, I''m using IM and not RM ! Is there any way of calculating an orthographic matrix using IM ? Or could it be built by hand ? Forgive me, but I''m not too hot on matrix maths !!

Another question, you mention that the resulting coordinate system is always the same regardless of the screen size etc. Does this mean that the bottom left corner will be (0,0,0) and the top right corner (1,1,0). So that I just scale with a factor less than 1.0 and then translate into the right position ??

If so, this is ideal !!

Andrew
Andrew,

The function D3DXMatrixOrthoLH() should be all you need to build that ortho matrix. You could do it by hand, but why bother? I assume you're using DirectX 8+, although your mention of IM and RM (immediate/retained mode?) makes me uncertain...

As for your second question, bligbug's approach would give you a view volume of 100 by 100 (these are specified in the D3DXMatrixOrthoLH() call). This means you can make your textured rectangles have sizes anywhere from 0x0 (invisible, of course) to 100x100 (filling the entire screen).

So, he's created a single 1x1 rectangle, which of course isn't too useful by itself since it's so tiny. However, he then uses a matrix to scale the rectangle to whatever dimensions it needs to be at render time. His scale factors would be from 1 to 100.

--Hoozit.

[edited by - HoozitWhatzit on October 3, 2002 1:38:30 PM]
----------------------Check out my game demo and resume at www.fivestory.com/projects/game.
I went through the whole four months of building a whole GUI. Allow me to toss a few free tips: The Ortho approach is a definite plus. I''ve done it with dynamic vertexes (one quad of vertexes per rectangle on screen) that I''d only lock and alter when the rectangles change coords, and got very good performance, but alas I can''t rotate, scale, twist or mangle my vertexes as freely as matrixes allow.

Go for Ortho!

Also, it''s great to have all the coordinates ''virtual'', winding up on screen at the same place regardless of resolution. (I used 10000x10000 virtual coords m''self) You might want to make it go from -1.0f to 1.0f and you''ll get free compatibility with the DirectX SDK samples D3DFont code, they use -1 to 1 for their scaled font.
One problem I ran into with virtual coords was when I tried to get pixel-precise. I realized that my using rectangles with ''Left, Top, Right, Bottom'' data caused trouble when scaling things. Whereas using rectangles with ''Left, Top, Width, Height'' would have saved me so many hassles! That''s my tip: Use Height-Width when you get around to saving rectangle sizes.
=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.
Thanks peeps !

It seems like the ideal way to go !

I am actually using DX7 Immediate Mode, so I''m not sure if that function exists to build the Ortho. Matrix.

Does it exist, or how else can I build it... ?

I''ll search the docs..

Thanks a million

Andrew
Why not just use DX8?
Programming is easy, thinking is hard.
Cos I already re-coded everything when I moved from DX6 to DX7, and I sure as hell aren''t doing it all again...

Is the format of the matrix:

1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 -1.0 0.0
0.0 0.0 0.0 -1.0

for left=-1, right=+1, top=+1, bottom=-1, near=-1, far=+1

?????

Got that using a formula from a book...

Can someone please try it in DX8 and see what matrix they get out of D3DXMatrixOrthoLH()

or even

D3DXMatrixOrthoLH(&ortho,100.0f,100.0f,0.0f,1.0f);

from below.

I can then set up my own routine to set the ortho projection matrix..

Andrew
That matrix must be wrong, since I''m not getting anything on the screen when using it..

Could someone verify what matrix they get out of

D3DXMatrixOrthoLH(&ortho,100.0f,100.0f,0.0f,1.0f);

and I''ll try to use that.

I would be eternally grateful...

Andrew

This topic is closed to new replies.

Advertisement