PDA

View Full Version : DirectX GUI Controls



Memphis
03-03-2008, 01:38 AM
hi there, im not certain this is the correct place to post this thread, but hopefully it is :oops: lol

anyways, i have recently started working with directx and delphi 7, i have created my device and window etc, now im having trouble starting to actually render lets say a dialog, ie a custom dialog, a square shape with a caption lol, i have no idea where to start or how todo it, i have searched for tutorials but i can't find any that are for beginning with such things....this including rendering custom buttons etc...

if anyone can point me in the right direction or maybe a link to a few basic samples of direct gui implementation would be greatly appreciated.

thanks in advance

-Memphis

czar
03-03-2008, 03:39 AM
If you are working with DirectX then you need to create your own visual components. i.e. buttons, edit fields. Not sure what you are making but a game tends to not have much in the way of gui so should take too make effort to create, and if you make in such a way that you can use the code for your other projects then even better.

chronozphere
03-03-2008, 09:50 AM
I developed NashaENGINE which is a DirectX 9 game engine. It has a GUI framework. You can check out the demo (Sound+GUI Demo, search the forums). :)

When you start to make your own directx based GUI framework, you'll need the following things.

> You must be able to render fonts (see fontstudio, or clooties font header).
> You must be able to render quads/rectangles. These can also be transparent if you want some cool effects.

Then you write a GUI base class with methods like render, click, mousemove and update. Finally you implement some GUI classes that implement this base class. You just describe their behaviour and appearance in these functions.

If you use DelphiX, i think this shouldn't be too hard. You can use a DirectDrawSurface for each dialog, and render the controls on it. Finally render the whole thing to the screen to make the dialog visible.

Hope this helps. ;)

Memphis
03-03-2008, 12:35 PM
hi, first off, thanks alot for replies :)

ok i use some custom directx headers, i have began creating my gui framework, but the part i was stuck is actually creating a directx rendered frame, lets say for my dialog or button, however i will check your nashaEngine, thanks alot :)

*edit*

i've checked your example, and that is the sort of thing i am trying to accomplish, but i still have no idea how to draw the custom shape in directx lol, i have also just checked clootie headers, but they are very complicated for starting off with dx....

chronozphere
03-03-2008, 01:53 PM
You are using DelphiX which works at a higher level than a lib that's build from scratch (like my engine). I have some DelphiX experience so i might be able to give you some clues and how-to's. I understand that you have problems getting shapes like rectangles on the screen. This can indeed be complicated (in my case, when using raw DX), but with DelphiX i guess it's a lot easier.

This is how i draw a rectangle using clooties headers:

> Define a vertex format (e.g D3DVTX_XYZ or D3DVTX_DIFFUSE)
> Create a Vertexbuffer and specify the defind vertex format
> Lock the buffer and fill it with vertex data
These vertices are the corners of triangles. I will pass 2 triangles which make up a rectangle.
> UnLock the vertexbuffer
> Enter the game loop and render the contents of the buffer in each frame.

As you can imagine, things like ellipses and round-rects are a lot harder to do because you need more vertices and more math skills to get your shape right. For more info on this, you can check the tutorials that are downloadable from clooties page. Things like: setting up a vertexbuffer, render a texture, creating a render device etc are all covered. :)

So, when you are using delphiX, you can use DXDraw1.Surface.Fill to fill a rectangle with a color. You can also draw rect's with DXDraw1.Surface.Canvas, but i guess you are not able to do blending. You can use more complex functions like ellipses and arc's though. Text can be done using Canvas.Textout.
You should explore the routines that the canvas and the surface offer you. Take a close look at the DelphiX examples, and i'm sure you will be able to figure it out.

If you have more specific problems, feel free to ask. ;)

EDIT: Never mind :oops:

Memphis
03-03-2008, 01:56 PM
'You are using DelphiX'

i do not use delphix, i use custom directx headers i have wrote, however, i think i get the idea of the vertex buffer, i will give that a shot, thanks

chronozphere
03-03-2008, 02:03 PM
Oops i can't read today :D

Well... i hope you figure out how it all works. 8)

Memphis
03-03-2008, 02:54 PM
ok i have another question related to this :-P

would you say it is better to create vertrices for creating buttons or would it be nicer to use sprites ?

thanks again

chronozphere
03-03-2008, 06:14 PM
You mean Vertexbuffers versus ID3DXSprite?

Well, i have to admit that i don't have experience with ID3DXSprite. I always render my geometry using vertexbuffers, because i can make it more abstract and reuse code for 3d purposes which ID3DXSprite can't handle.

I guess both are good options. Doing it using vertexbuffers takes some extra work, and problems might occur. But you can use the same code for rendering 3d things, and you have much control over the rendering process. I think that ID3DXSprite gives you enough flexibility to make a GUI, but i can't help you with it. :)

Memphis
04-03-2008, 07:39 PM
hi i have decided to go with using vertices, so far i have designed a custom form, which i can place via...



TestDialog := TNemesisDialog.Create(5,35,150,250);


like so:

http://www.meka-meka.com/meka/n1.PNG

next thing i want todo is make buttons etc, but small question is, is there a special trick to detecting mouse over etc, when dealing with directx?

at the moment i have jus wrote a small function todo the job


function TNemesisControl.TestHit(H, W: Integer): boolean;
var
m: TPoint;
begin
Result := True;
GetCursorPos(m);
ScreenToClient(hWindow, m);

if (m.X < iPosX) or (m.X > iPosX + W) or (m.Y < iPosY) or (m.Y > iPosY + H) then Result := False;
end;



thanks in advance,

-MM

chronozphere
05-03-2008, 10:03 AM
I think you are doing it the right way. DirectX is very low-level so it doesn't contain any mouseover functions. You can retrieve the mouse-position using DirectInput but you can also use the default Delphi-Events or WINAPI functions, it doesn't matter. I use the standard delphi events to retrieve mouse coords.

So i guess your code is the way to go. If it works for you, it's OK ;)

Memphis
05-03-2008, 05:08 PM
ok great, thanks chronozphere...

now i jus need figure out how to create a border around buttons and dialogs etc, any pointers you could give me?

also problem finding info on rendering an image to the window, ie as the background image.. thanks again, you've been very helpful

-MM

*edit* here is what i have done so far > http://www.meka-meka.com/meka/Nemesis.rar

chronozphere
06-03-2008, 09:50 AM
I'm glad i can help. ;)

A border around a button and a button image can be done by rendering textured quads. For texturing i would suggest this tutorial:

http://www.two-kings.de/tutorials/dxgraphics/dxgraphics05.html

The only difference is that you need a Quad (rectangle), not a pyramid. I'm sure you can figure out the coordinates for a textured quad yourself. ;)

This way, you can render images. You can use them as background for your window, or titlebar. You can also use them for your buttons. If you only want a border for your buttons i would suggest you use an image that is transparent in the center, and only has color at the borders.

You can get even cooler effects when you combine Diffuse colors with textures. You can give your images colors, and blend them with the background. You have to include D3DFVF_DIFFUSE and D3DFVF_TEX1 in your texture format definition. Also make sure that your renderstates and sampler-states are correct. This can be a little tricky. Check the following tut (alpha blending only):

http://www.two-kings.de/tutorials/dxgraphics/dxgraphics07.html

When i get home.. i will take a look at your work so far. :)

Memphis
06-03-2008, 03:26 PM
hi, great thanks, only problem is that if the virtual form size is changed, it will strentch the texture and make the border bigger ? as i'd like to try make it resemble a real form... thanks again

chronozphere
07-03-2008, 07:13 PM
Hmm.. that's true.

Then i would suggest you render a quad for each side of the dialog (Textured or not) ;)

Memphis
07-03-2008, 09:59 PM
ok yes that is what i will do thanks, what do u think of my test app? :)

Memphis
08-03-2008, 01:53 AM
hm im having few problems also with this line

NemRes.FFont.DrawTextA(nil, 'testing', -1, @NemRes.FFontPos, DT_NOCLIP, $026AFE);

i have created the font object etc, nemres is a struct fontpos is a rect

as soon as i call this the app uses 100% cpu and stops rendering.

any sugestions ?

thanks in advance.

Memphis
08-03-2008, 05:57 PM
hi, ok i've been messing around i missed a char is why it didnt render the text, however, now as soon as i move the directx window, it uses 100% cpu.

*edit* nm that, i have solved the problem, thanks anyways

-MM

chronozphere
08-03-2008, 06:30 PM
Yummie.. draggable windows :D I like that.

Your test app looks great so far. :) Keep it up.

Memphis
09-03-2008, 01:35 PM
hi, when my app is rendering, no matter what spec of pc, it seems to sit around 60fps, and uses 0% cpu no matter what.... but if i cover the window with another, it continues its routines but runs at 50% cpu and goes at around 2300fps.. i checked your nasha engine for reference and i see it also uses around 40-50% cpu....

so i tried running the render process on a seperate thread in a constant loop, but it stil used 0% cpu and sat at 60fps. again covering the window then moving the window out of the way, caused it to run at 2300fps for a v.short period, is there any hints or tips you could give me on this situation?

thanks in advance.

-MM

chronozphere
10-03-2008, 10:21 AM
Yeah i know that problem. When some annoying text baloon pop's up from the system tray, my game usually slows down. Sometimes, it goes from 400/500 FPS to 100/80 FPS.

It's very weird that your FPS increases when the window is partially covered.
I guess you have enabled V-Sinc (look at the parameters you pass to D3D when you create your device). That causes your app to run at 60 FPS by default.

Are the content's of your screen updated when another screen partially covers the window?? If not, i guess that's the reason why your FPS increases, because Direct3d doesn't update the window.

Maybe you can show me your render loop code?

Memphis
10-03-2008, 01:13 PM
hi, not when partially closed, it has to be fully covered, then after moving it out the way it is running at a much higher framerate...

dx params:

with EParams do begin
hHandle := h;
bFullScreen := False;
bInitDeviceOnCreate := True;
iResWidth := 800;
iResHeight := 600;
iTotalBackBuffer := 1;
iColorDepth := D3DFMT_A8R8G8B8;
end;


basically furthur into initilization of my engine i call.


Engine.EnterLoop;


which is as follows:


procedure TNemesisEngine.EnterLoop;
var
msg: TMsg;
begin
PeekMessage( msg, 0, 0, 0, PM_NOREMOVE);

while (WM_QUIT <> msg.message) do begin
if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then begin
// Translate and dispatch the message
TranslateMessage(msg);
DispatchMessage(msg);
end;

Render;
end;
end;


and render is:


procedure TNemesisEngine.Render;
var
i: Integer;
cont: TNemesisControl;
curtick: Int64;
begin
if (NemRes.FDXDevice = nil) then exit;

// Clear the backbuffer to black
NemRes.FDXDevice.Clear(0, nil, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0, 0);

// begin the scene
if Succeeded(NemRes.FDXDevice.BeginScene) then begin
// Rendering of scene objects can happen here

for i := 0 to NemRes.FComponents.Count-1 do begin
cont := NemRes.FComponents[i];
cont.Render;
end;

for i := 0 to FStaticControls.Count-1 do begin
cont := FStaticControls[i];
cont.Render;
end;

// End the scene
NemRes.FDXDevice.EndScene;
end;

// Present the backbuffer contents to the display
NemRes.FDXDevice.Present(nil, nil, 0, nil);

//check fps...
QueryPerformanceCounter(curtick);
NemRes.iFPS := (curtick - NemRes.iFTPTick) div 1000;
NemRes.iFTPTick := curtick;
end;


each control render is a virtual method so its basically just drawing the controls etc, but if i remove the whole draw procedure, it still runs at 60fps.....

-MM

chronozphere
10-03-2008, 03:41 PM
Sorry.. i ment the TD3DPresentParameters (http://msdn2.microsoft.com/en-us/library/bb172588.aspx) structure.

You should try to set PresentationInterval to D3DPRESENT_INTERVAL_IMMEDIATE. That will disable V-Sync. You will get higher framerates, even when you are not covering the window. :)

Can you show me your FPS calculation code. There might be a bug in it.

Memphis
10-03-2008, 03:58 PM
hi, thanks again for replying, it seems D3DPRESENT_INTERVAL_IMMEDIATE has done the trick, now it runs around 900-1000fps, but the only problem is now when moving the virtual windows it slices the screen, i tried differ interval settings... ie..

D3DPRESENT_INTERVAL_DEFAULT = $00000000;
D3DPRESENT_INTERVAL_ONE = $00000001;
D3DPRESENT_INTERVAL_TWO = $00000002;
D3DPRESENT_INTERVAL_THREE = $00000004;
D3DPRESENT_INTERVAL_FOUR = $00000008;

however, the onlyones that seemed to work is interval_one, default and immediate, the others crashed the application as soon as it started....

example of screen slice > http://www.meka-meka.com/meka/Nemesis.rar

thanks again for all your help.

chronozphere
10-03-2008, 04:53 PM
Sorry i don't know what you mean. I can move your virtual windows here without seeing any artifacts or slices. Do you mean that when moving the upper half of the window is at another position (horizontally) than the lower half?

This might be because your graphics hardware is slower than mine. Can you give me your specs?

If it doesn't look good on your machine, i suggest you turn V-Sync on again and find another sollution (i can't think of any yet, if i do i'll let ya know). :)

You say your FPS increases when you covered your window. :? Does it restore quickly to a normal number? How do you calculate your FPS?

It might be an idea to render something that moves (e.g a bouncing rectangle). Cover and uncover your window again. Does the rectangle move faster than normal?? This is a way to determine whether the framerate has actually increased or you FPS-code is not working properly.

Hope it helps. ;)

Memphis
10-03-2008, 05:05 PM
hi, sorry i think i have small prob with my psu, gonna check it out, losing power so it seems lol, and my hardware is deffy fine lol, i run a business selling hardware and software + repairs :-P



CPU&#58; 1.86GHz Core 2 Duo
Mem&#58; 4GB DDR2 667
GFX&#58; BFG 7950GT 512MB
O/S&#58; Windows XP Pro

Monitor&#58; 24" LCD 5ms Response &#40;1920x1200 res&#41;


im gonna go check out my psu, will post back if all solved, thanks again for tips and help, at least now app works perfect :)

*edit* 1 other thing is, atm i use a single png to create texture for buttons etc, however i see many places have a dds file with 3-4 images in to create the somewhat sprite texture or to use the same image for several parts of a quad etc, is there any tutorial on doing this? i cant seem to find one, thanks again

-MM

chronozphere
10-03-2008, 08:23 PM
*edit* 1 other thing is, atm i use a single png to create texture for buttons etc, however i see many places have a dds file with 3-4 images in to create the somewhat sprite texture or to use the same image for several parts of a quad etc, is there any tutorial on doing this? i cant seem to find one, thanks again


Do you mean Tilesets (an image that is composed of multiple smaller images)?? That's quite easy to achieve. So far you only used 0.0 and 1.0's for you texture coordinates (they use U and V instead of X and Y). When you want to render only the upper half of your image, you can use the following coords:


//setting up the quad

//top left vertex (top left on texture)
Vertex[0].u := 0.0;
Vertex[0].v := 0.0;
//top right vertex (top right on texture)
Vertex[1].u := 1.0;
Vertex[1].v := 0.0;
//bottom left vertex (halfway down - left on texture)
Vertex[2].u := 0.0;
Vertex[2].v := 0.5;
//bottom right vertex (halfway down - right on texture)
Vertex[3].u := 1.0;
Vertex[3].v := 0.5;


It may take some fiddling before your orientation is right, but i guess you are smart enough to figure that out yourself. ;)

Good luck with your PSU. :)

Memphis
10-03-2008, 10:37 PM
hi, i solved my PSU issue, ok, so far i've rewritten 70% of my engine, now it is much cleaner and should be quicker, however what i ment with the texture problem is... well for example....

http://www.meka-meka.com/meka/sampletexture.PNG

so instead of loading 2 differ png files for 1 button, with a up state texture and a down state texture, i see many use 1 png file to load the 2 differ textures.

also wonder if you know why D3DCREATE_SOFTWARE_VERTEXPROCESSING would be better framerate then D3DCREATE_HARDWARE_VERTEXPROCESSING

with new engine i get now 2300-2600fps on software_vertex proc but with hardware proc i get 350-400fps

thanks

chronozphere
11-03-2008, 03:42 PM
also wonder if you know why D3DCREATE_SOFTWARE_VERTEXPROCESSING would be better framerate then D3DCREATE_HARDWARE_VERTEXPROCESSING

with new engine i get now 2300-2600fps on software_vertex proc but with hardware proc i get 350-400fps


Hmm.. that's odd. Hardware should be faster than software. Maybe you should update your drivers :? I guess that's a hardware problem or driver problem. Testing your app on different hardware machines might give you a good idea of what's going on. Can you upload it again? :)

Can you give me the code you use to set up your quad? Then i can modify it for you to render a part of a texture. (So you can render both sub-images seperately) :) It isn't that hard. Didn't you understand my explanation about the texture coordinates? :?

Memphis
11-03-2008, 05:21 PM
sorry yes, i mis-understood the above post, i understand now thanks :)

since i've rewrote engine it is farrrrr quicker then before, i've made massive changes to it also, the way virtual forms work, there is now what i call a dragbar, and the plain square control, you can setup colour schemes for everything etc.. now it runs average 2900-3500fps

http://www.meka-meka.com/meka/3000p.PNG

i will soon upload new test app, i have very many more controls yet to add.....


*edit*

i use for drawing fonts >
F_Font : IID_ID3DXFont;

is this slow? if i print 2 texts it runs around 3000-3500fps, if i remove 1 label, it runs around 4500fps

http://www.meka-meka.com/meka/4500p.PNG

-MM

chronozphere
11-03-2008, 07:56 PM
I guess your performance loss is perfectly acceptable.. A decrease of a thousand frames per second seems a lot, but when you look at it from a mathematical point, it isn't that bad.

I took my calculator to show you why:



Rendering 4500 frames per second (= 1000ms), means that rendering one frame takes:

1000/4500 = 0.22 ms

Now.. when your FPS drops to 3500, a frame will render in:

1000/3500 = 0.28ms


So rendering the second label only takes 0.06 ms which is perfectly acceptable if you ask me. ;) Rendering text is usualy slower than rendering quads because under the hood, D3D is rendering a quad for each character (If i'm not mistaking).



Now when you want to render 200 labels, it would theoraticly take:

0.22 + (200 * 0.06) = 12.2ms

Which results in an FPS of

1000/12.2 = 81 FPS.

Which is still acceptable, if i'm concerned. :)


This is all theory. If you can optimize your render code, you can get far better performance than 81 FPS. Please note that changing renderstates also takes time. You only have to do this once when rendering those 200 font's. ;)

Pre-rendering all your labels would give you a speed increase, but i doubt whether it's worth the effort. :?

Memphis
11-03-2008, 08:01 PM
hi, i see what u mean, thanks, but is there any faster methods of displaying text ? thanks again

chronozphere
11-03-2008, 08:44 PM
Yeah... pre-rendering the text (for example make your texts in photoshop and render them using a single quad).

You can also expiriment with it by making your own font rendering methods (like i did). ;)

Memphis
11-03-2008, 10:59 PM
Yeah... pre-rendering the text (for example make your texts in photoshop and render them using a single quad).

You can also expiriment with it by making your own font rendering methods (like i did). ;)

so i could make each letter in photoshop, load them as a texture and render quads of letters? this will be worth the effort or do you think it will not make too much difference?

thanks


btw, my latest tweaks have made big difference also>

http://meka-meka.com/meka/6000p.PNG


-MM

chronozphere
12-03-2008, 03:47 PM
Nope.. you misunderstood me. I mean that you pre-render your TEXT, not a set of characters. It will definitly be a lot faster, but you'll loose a lot of flexibility. :)

You can also render your texts to bitmaps when you start the game. Then you don't need to do it all by yourself in photoshop. ;)

But i think it's not the best way because you cannot display random text anymore. You better make your own font-system or be satisfied with the one you currently use.

Memphis
14-03-2008, 11:34 PM
hi again, i decided for to stick with the way i was outputting fonts for now, once i come to need for something different, i can add it it... my current progress now is >

http://www.meka-meka.com/meka/TO.PNG

however, i have ran into a new problem, drawing custom textboxes, well i can draw the textbox but, i've no idea to allow user input... is there any tutorials for this sort of controls? thanks.

chronozphere
15-03-2008, 08:22 AM
Looking good! :)

About the user-input. I think you should do this by catching windows messages. If you use DirectInput you'll loose some text-editing features (e.g when you are pressing the "a", only one "a" appears but if you hold it for one sec, a lot of them will be added).

I'm not going to explain this because i haven't even done this yet, and i think you are able to figure this out yourself. You should look at WM_CHAR messages (also check MSDN for other types of windows messages that may become handy). I recall that delphi.about.com has some stuff about message handling. (http://delphi.about.com/od/windowsshellapi/l/aa111503a.htm) You might also want to take a look at that.

Good luck! ;)

Memphis
15-03-2008, 05:34 PM
hi thanks for reply, yes i understand how to capture the characters, but its allowing the user to click the textbox and have the beam pointer stay onto the editbox that i dont understand...

thank again.

-MM

chronozphere
15-03-2008, 06:14 PM
That shouldn't be too hard. You will need the following:

> A way of retrieving the mouse coordinates (which i assume you allready have, because you allready made buttons).
> A way to render a rectangle, and a cursor line (Take a look at rendering line-lists (http://www.tar.hu/directx9kick/ch04lev1sec1.html) in Direct3D using D3DPT_LINELIST.)
> You should have a routine to determine the width of a text, so you know where to put the cursor line. As i'm using my own font system, i cannot say what function you should use for it. maybe ID3DXFont has one.

Can you describe your problem in a more specific way. I can write pages of info for you, but i don't want to do that. You must try first, and ask some more specific questions. ;)

Memphis
16-03-2008, 08:45 PM
hmm i have got to point of rendering text box and text inside, but i cant seem to find a way to get width of text, ie char count that fits inside the box etc.... if i decided to make a font/text lib.... is i loaded png file with characters, how could i change the colour of the font?

thanks,

-MM

chronozphere
16-03-2008, 09:03 PM
that's very easy. When your image with the chars is grayscale (background black and chars white), you can use the diffuse color of your vertices to give the characters a color. :)

I advice you to study clooties font code. If you don't understand things, use google to find out what they are about. I'm sure it will give you a good idea on how font rendering works.

If you happen to use ID3DXFont, i can tell you that there is a way to determine the text size. You have to call ID3DXFont::DrawText with the DT_CALCRECT flag. It will not render anything, but instead it gives you the rectangle that will be occupied when rendering the text. Look at the following link for more info:


http://msdn2.microsoft.com/en-us/library/bb173962.aspx

Memphis
22-03-2008, 06:30 PM
hi, i came to thank you again for help etc, i have now come a far way with my gui system and it works superb, few improvements i can still make in the future, now i have written my gui engine, i'd like to start on some platform engine to get the hang of this next...

i didnt think there was no point to open a new thread for this 1 question:

is there any examples of 2d platform games, using sprites etc, ie, screen follows the player on a map.

*edit* or v.good tutorial that you can recommend

thanks in advance

-MM

chronozphere
22-03-2008, 10:19 PM
I'm glad to hear that everything's running smooth. :D

As for the tutorials, i would suggest these:

http://www.gameprogrammer.net/index.php?fuseaction=tutorials.list
http://www.cerebral-bicycle.co.uk/links.asp?cat=24&subj=5

I think you should take a look at DelphiX (and maybe some other populair game libraries). There are a lot of delphix tutorials available who show how to deal with sprites. I learned a great deal by studying those sources.

Good luck!

Memphis
23-03-2008, 06:01 PM
hi, thanks for reply, they seemed a bit odd tbh lol, more based on tile based games, however what im thinking of doing is....

lets say i do same as drawing a a 2d virtual window again... but only it will be a quad textured with some stone or something, and many other shapes.... a question i have is.... is there some specific api i can use for camera on a 2d platformer, or do i move the quads and draw them in place..

so its not really the character moving on screen, its the rest of the 2d world ?

thanks in advance.

chronozphere
23-03-2008, 07:06 PM
is there some specific api i can use for camera on a 2d platformer


nope.. but it's not that hard.

I would setup my camera at a fixed point and move the whole scene when the character is walking. But it doens't really matter.. i think both ways would work. If you have some knowledge about vectors you will be able to fix this. :)

Memphis
23-03-2008, 07:30 PM
yes thanks, i have idea of where to start, i jus didnt want to go ahead in case i was wasting my time, thanks again

-MM

Memphis
24-03-2008, 04:45 PM
i seem to find this alot in samples



D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH&#40; &matProj, D3DXToRadian&#40; 45.0f &#41;, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 100.0f &#41;;
g_pd3dDevice->SetTransform&#40; D3DTS_PROJECTION, &matProj &#41;;


but i dont understand what this is for, is there any straight forward explanations for this and what its use is for, from what i see, it is some help for moving the scene? seems most calls to move change maxtrix perspectives, but still dont get it tbh,

thanks,

chronozphere
24-03-2008, 05:12 PM
Did you look on MSDN?? Documentation on this can be found there. :)

What i remember about D3DXMatrixPerspectiveFovLH:

First parameter is the destenation matrix (result of the routine).
Second parameter is the field of view in radians (i would use 90 degrees or 0.5 * Pi radians).
Third parameter is the aspect ratio, and the fourth and fifth are the z value's for the near and far plane (minimum and maximum visible Z coords).

If you want to make a 2d game, i would advice you to use D3DXMatrixOrthoLH (http://msdn2.microsoft.com/en-us/library/bb205346.aspx) instead. Your sprites will look the same, regardless of their z-values, so you have perfect control over the position, dimentions and depth of your sprites.

About your question about moving the scene. You are looking at the wrong piece of code. Take a look at this routine (http://msdn2.microsoft.com/en-us/library/bb205342.aspx). It allows you to setup a camera and point it somewhere. The resulting matrix should be set using SetTransform(D3DTS_VIEW, myViewMatrix).

Good luck.

Memphis
24-03-2008, 05:46 PM
hi thanks, ok i've read up a bit on that, atm my map is made up of sprites, such as walls, land surface etc, before drawing the sprites they all have an offset like so:



iLeft &#58;= F_Left - F_Res.Player.MapPosX;
iTop &#58;= F_Top - F_Res.Player.MapPosY;


then ileft, itop is used as the position, f_left is actual position... would it be better to use current method or to get into using the different procedures?

baring in mind, my plan was to calculate the offscreen distance, if offset then skip rendering that specific sprite etc, would i still be able todo that with the matrix procs?

chronozphere
24-03-2008, 06:10 PM
would it be better to use current method or to get into using the different procedures?


I'm not sure what you mean. I think you should try it, and find out what works for you instead of just asking it. Please only ask something when you are really stuck, without any clue how to fix the problem. Looking at sources will give you a lot of answers and when you are somewhat more experienced, you will be able to make your own choices based on your experience. That's way better then just asking and nitpicking about every issue you stumble upon (no offence though). ;)



baring in mind, my plan was to calculate the offscreen distance, if offset then skip rendering that specific sprite etc, would i still be able todo that with the matrix procs?


I'm not sure what you mean here, but AFAIK it's all possible with matrices. You can draw your sprite everywhere on the screen with every scale and angle you want. :)

Memphis
26-03-2008, 12:31 AM
hi, ok i have tried differ ways and i think moving the quads left or right is probably best way... but im having alot of problems now... for some reason it jitters when moving and i have no idea where im going wrong

example:

http://www.meka-meka.com/meka/FuryEngine.rar

my render code....

>main engine

procedure TFury.ProcessKBInput;
var
buffer: array[0..255] of byte;
hr: HResult;
tick: Cardinal;
begin
hr := F_DIDevice.GetDeviceState(SizeOf(buffer), @buffer);
if FAILED(hr) then begin
WriteLN('FAIL');
exit; //**** knows.... probably try to reaquire, todo...
end;

tick := GetTickCount;

if (buffer[DIK_LEFT] and $80) <> 0 then
F_MapBuilder.Player.PosX := F_MapBuilder.Player.PosX + (((tick - F_LastTick) / 60) * 15)
else if (buffer[DIK_RIGHT] and $80) <> 0 then
F_MapBuilder.Player.PosX := F_MapBuilder.Player.PosX - (((tick - F_LastTick) / 60) * 15);
end;


procedure TFury.Render;
begin
if F_DXDevice = nil then exit;

// clear the backbuffer to black
F_DXDevice.Clear(0, nil, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0, 0);

// Rendering of scene objects can happen here
F_DXDevice.BeginScene;
begin
//get user input.
ProcessKBInput;

F_MapBuilder.DrawBricks;
end;
F_DXDevice.EndScene;
F_LastTick := GetTickCount;

// Present the backbuffer contents to the display
F_DXDevice.Present(nil, nil, 0, nil);
end;





procedure TMapBuilder.DrawBricks;
var
i: Integer;
brick: TCustomBrick;
begin
GetDevice.SetFVF(D3DFVF_BRICKVERTEX); //D3DFVF_TVERTEX);
//draw our bricks.

//later add check for if char has moved else dont update position...

//for i := F_Bricks.Count-1 downto 0 do begin
for i := 0 to F_Bricks.Count-1 do begin
brick := F_Bricks[i];
brick.UpdatePos;
brick.Draw;
end;
end;


in which case >


procedure TBrick.Init;
var
iLeft, iTop, iWidth, iHeight: Single;
begin
iLeft := F_Spec.F_PosX;
iTop := F_Spec.F_PosY;
iWidth := F_Spec.F_Width;
iHeight := F_Spec.F_Height;

F_Vertices[0] := SetVertexUV(iLeft, iTop, 0, 0, 0, 0);
F_Vertices[1] := SetVertexUV(iLeft+iWidth, iTop, 0, 0, 1, 0);
F_Vertices[2] := SetVertexUV(iLeft+iWidth,iTop+iHeight, 0, 0, 1, 1);
F_Vertices[3] := SetVertexUV(iLeft, iTop+iHeight, 0, 0, 0, 1);
end;

procedure TBrick.UpdatePos;
var
NewX, NewY: Single;
begin
NewX := Ceil(F_Spec.F_PosX + Builder.Player.PosX);
NewY := Ceil(F_Spec.F_PosY + Builder.Player.PosY);

//update position
F_Vertices[0].x := NewX;
F_Vertices[0].y := NewY;

F_Vertices[1].x := NewX+F_Spec.F_Width;
F_Vertices[1].y := NewY;

F_Vertices[2].x := NewX+F_Spec.F_Width;
F_Vertices[2].y := NewY+F_Spec.F_Height;

F_Vertices[3].x := NewX;
F_Vertices[3].y := NewY+F_Spec.F_Height;
end;

procedure TBrick.Draw;
begin
//check if it is worth drawing
if (F_Vertices[1].x <= 0) or (F_Vertices[0].x >= GetEngine.FPresentParam.BackBufferWidth) then exit;

//draw it etc
with GetDevice do begin
SetTexture(0, F_Texture.Texture);
DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, F_Vertices, SizeOf(TBrickVertex));
end;
end;


F_Vertices is saved as an array inside the brick object... the texture is a pointer to a texture array object.. in this case they all point to array object 0.... hope you can help, i've been on with this for hours and still cant get it to move smoothly....

the framerate sits around 4000-5000fps, you can see this in the console if u move main window.

thanks,

-MM