Sign in to follow this  
neo187

draw a connecting line in 3d space?

Recommended Posts

Hi there,

I can't seem to find any info on how to obtain a line in space made from a number of vertices. The line would need to be drawn from the moving character to a moving point in space (which represents the crosshair), so it'd be sort of like a ray but it'd need to be made of a number of vertices since i'd like to apply some algorithms to change the positions of those vertices with the sound of the music (using FMOD)...

I really just need to know how to put these vertices in space and connect them with a line...

Any suggestions?

Thank you very much

Share this post


Link to post
Share on other sites
On a similar post here someone suggested to use the following code:

D3DTLVERTEX vertex[2];
int x=5,y=6,x2=20,y2=60;

vertex[0]=D3DTLVERTEX(D3DVECTOR(x,y,0.0),1.0,RGB_MAKE(255,255,255),0,0,0);
vertex[1]=D3DTLVERTEX(D3DVECTOR(x2,y2,0.0),1.0,RGB_MAKE(255,255,255),0,0,0);

// Then draw it with:


lpD3DDevice->DrawPrimitive(D3DPT_LINESTRIP,D3DFVF_TLVERTEX,&gridVertex,2,0);



but the compiler tells me that DrawPrimitive does not take 5 arguments? And it also doesn't recognise D3DTLVERTEX....

Share this post


Link to post
Share on other sites
Read the DX SDK documentation on DrawPrimitive. The primitive type is one of the parameters to that method, but the other parameters you pass to it do not make sense at all.

Also, you do know that in order for DrawPrimitive to actually use your vertex data, you must upload said data to the device by using vertex buffers, and set the vertex layout or the FVF of the data separately?

There is also a DrawPrimitiveUP method that can take a user memory pointer to the vertex data and upload it automatically, at the potential cost of performance in some common scenarios. However, your parameters don't fit that either.

Share this post


Link to post
Share on other sites
I'm sure he meant "DrawPrimitiveUP":

Quote:

HRESULT DrawPrimitiveUP(
D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount,
CONST void* pVertexStreamZeroData,
UINT VertexStreamZeroStride
);



Edit @Nik02: Sorry, missed your last sentence.

Share this post


Link to post
Share on other sites
Yea, but his parameters do not make sense even if he did mean to use that method.


  • The DPUP takes 4 parameters, but he has 5
  • The vertex data is originally written in an array variable named "vertex", but the variable passed to the method is a pointer to a variable named "gridVertex"
  • If you have two vertices, you only have one primitive of a line strip
  • Neither 0 nor 2 is a possible match for the vertex stride


This is from a quick glance only.

Share this post


Link to post
Share on other sites
Quote:
Original post by mind in a box
Edit @Nik02: Sorry, missed your last sentence.


I edited my post a little bit just after posting it. Sorry for the confusion :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Nik02
Yea, but his parameters do not make sense even if he did mean to use that method.


  • The DPUP takes 4 parameters, but he has 5
  • The vertex data is originally written in an array variable named "vertex", but the variable passed to the method is a pointer to a variable named "gridVertex"
  • If you have two vertices, you only have one primitive of a line strip
  • Neither 0 nor 2 is a possible match for the vertex stride


This is from a quick glance only.


Ok so I modified those lines that were suggested in the other post and changed to function to DrawPrimitiveUP

D3DXVECTOR3 vertex[2];
vertex[0]=D3DXVECTOR3(1.0f, 1.0f, 1.0f);
vertex[2]=D3DXVECTOR3(7.0f, 10.0f, 7.0f);
device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,&vertex,0);



This one compiles ok but when I run it I get a " Stack around the variable 'vertex' was corrupted" error.... Could it be because of D3DXVECTOR3 type used? Or because I have to declare vertex as a class variable instead of calling these lines in the Render bit?

Thanks for the help

Share this post


Link to post
Share on other sites
Quote:


D3DXVECTOR3 vertex[2];
vertex[0]=D3DXVECTOR3(1.0f, 1.0f, 1.0f);
vertex[2]=D3DXVECTOR3(7.0f, 10.0f, 7.0f);//ERROR
...


You have wrote beyond array bounds, try:

D3DXVECTOR3 vertex[2];
vertex[0]=D3DXVECTOR3(1.0f, 1.0f, 1.0f);
vertex[1]=D3DXVECTOR3(7.0f, 10.0f, 7.0f);


i am suprised you are not getting any warnings from compiler?

I think you got one more error in your code:
Quote:


device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,&vertex,0);



try:

device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,&vertex[0],0);

or:

device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,vertex,0);

Share this post


Link to post
Share on other sites
Quote:
Original post by belfegor
Quote:


D3DXVECTOR3 vertex[2];
vertex[0]=D3DXVECTOR3(1.0f, 1.0f, 1.0f);
vertex[2]=D3DXVECTOR3(7.0f, 10.0f, 7.0f);//ERROR
...


You have wrote beyond array bounds, try:

D3DXVECTOR3 vertex[2];
vertex[0]=D3DXVECTOR3(1.0f, 1.0f, 1.0f);
vertex[1]=D3DXVECTOR3(7.0f, 10.0f, 7.0f);


i am suprised you are not getting any warnings from compiler?

I think you got one more error in your code:
Quote:


device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,&vertex,0);



try:

device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,&vertex[0],0);

or:

device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,vertex,0);


Oh yeah, wrong array index, it runs ok now but nothing gets shown on screen...could it be because I'm using D3DXVECTOR3 instead of D3DLVERTEX like suggested in the other post?
Cos when I try and use D3DLVERTEX I keep getting an undeclared identifier error, even after including <ddraw.h> which I seem to understand is the required header...

Thanks for the help!

Share this post


Link to post
Share on other sites
Quote:

Oh yeah, wrong array index, it runs ok now but nothing gets shown on screen...

Did you setup "camera" in your scene? like:

//global
D3DXMATRIX world, view, proj;
...
//in some init function
D3DXMatrixIdentity(&world);
D3DXVECTOR3 pos(0.0f, 0.0f, -100.0f);//move back a bit
D3DXVECTOR3 lat = vertex[0];//look at vertex 1
D3DXVECTOR3 upd(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&view, &pos, &lat, &upd);
float aspect = (float)ScreenWidth / (float)ScreenHeight;
float fov = D3DXToRadian(60.0f);
D3DXMatrixPerspectiveFovLH(&proj, fov, aspect, 1.0f, 1000.0f);
...
//in some render function
device->SetTransform(D3DTS_WORLD, &world);
device->SetTransform(D3DTS_VIEW, &view);
device->SetTransform(D3DTS_PROJECTION, &proj);
RenderLines();//function that render lines


Quote:

...could it be because I'm using D3DXVECTOR3 instead of D3DLVERTEX like suggested in the...

I doubt that D3DLVERTEX is part of DX SDK it must be some custom header that you failed to include/download with that demo? but it doesnt matter if it is used only for storing position.

Share this post


Link to post
Share on other sites
Quote:
Original post by belfegor
Quote:

Oh yeah, wrong array index, it runs ok now but nothing gets shown on screen...

Did you setup "camera" in your scene? like:

//global
D3DXMATRIX world, view, proj;
...
//in some init function
D3DXMatrixIdentity(&world);
D3DXVECTOR3 pos(0.0f, 0.0f, -100.0f);//move back a bit
D3DXVECTOR3 lat = vertex[0];//look at vertex 1
D3DXVECTOR3 upd(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&view, &pos, &lat, &upd);
float aspect = (float)ScreenWidth / (float)ScreenHeight;
float fov = D3DXToRadian(60.0f);
D3DXMatrixPerspectiveFovLH(&proj, fov, aspect, 1.0f, 1000.0f);
...
//in some render function
device->SetTransform(D3DTS_WORLD, &world);
device->SetTransform(D3DTS_VIEW, &view);
device->SetTransform(D3DTS_PROJECTION, &proj);
RenderLines();//function that render lines


Quote:

...could it be because I'm using D3DXVECTOR3 instead of D3DLVERTEX like suggested in the...

I doubt that D3DLVERTEX is part of DX SDK it must be some custom header that you failed to include/download with that demo? but it doesnt matter if it is used only for storing position.

Yes there is already a camera and other models moving about, but this line just won't appear. In the render function of the main class I currently have (as per a tutorial seen):

D3DTLVERTEX vertex[2];
int x=0,y=1,x2=20,y2=60;

vertex[0]= CreateD3DTLVERTEX(x, y, 0.0f, 1.0f, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 0.0f);
vertex[1]= CreateD3DTLVERTEX(x2, y2, 7.0f, 1.0f, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 0.0f);

const DWORD D3DFVF_TL = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
device->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
device->SetFVF( D3DFVF_TL );

device->DrawPrimitiveUP(D3DPT_LINESTRIP,2,&vertex[0],0);



but nothing will show up...I'm about to give up on it....but thanks a lot for the help!

Share this post


Link to post
Share on other sites
From FVF declaration i can see that D3DTLVERTEX should look like this:

struct D3DTLVERTEX
{
D3DXVECTOR4 pos;
DWROD color;
float tu;
float tv;
};

which holds pretransformed vertices!

and CreateD3DTLVERTEX() function like this:

D3DTLVERTEX CreateD3DTLVERTEX(float px, float py, float pz, float pw, DWORD color, float tu, float tv)
{
D3DTLVERTEX result;
result.pos.x = px;
result.pos.y = py;
result.pos.z = pz;
result.pos.w = pw;
result.color = color;
result.tu = tu;
result.tv = tv;
return result;
}

Share this post


Link to post
Share on other sites
I'll reiterate one point that I made in my earlier reply: If you have two vertices, you have only one primitive of a line strip.

The camera shouldn't have any effect since you're using the RHW component in the geometry (meaning that you supply vertices that you've already transformed).

The default viewport of D3D9 clips the z range from 0 to 1; yet, your second vertex has z of 7.0f. In effect, if the line would otherwise go from [0,0] to [20,60], it would get clipped to roughly 1/7th of its length [2.857,8.571] so it wouldn't be as noticeable on the screen.

Try to disable lighting so as to make sure that your line isn't black, and clear your background to some color other than black so as to see the geometry if it does turn out black. Black is a common color for geometry when lighting logic fails for some reason.

Also, don't mess with alpha blending until you get the basics working. It may inadvertently hide geometry that would otherwise be visible.

Share this post


Link to post
Share on other sites
Quote:

The camera shouldn't have any effect since you're using the RHW component in the geometry...

I didnt know if he was using pretransformed vertices so i sugested if he is setting up a camera already.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nik02
I'll reiterate one point that I made in my earlier reply: If you have two vertices, you have only one primitive of a line strip.

The camera shouldn't have any effect since you're using the RHW component in the geometry (meaning that you supply vertices that you've already transformed).

The default viewport of D3D9 clips the z range from 0 to 1; yet, your second vertex has z of 7.0f. In effect, if the line would otherwise go from [0,0] to [20,60], it would get clipped to roughly 1/7th of its length [2.857,8.571] so it wouldn't be as noticeable on the screen.

Try to disable lighting so as to make sure that your line isn't black, and clear your background to some color other than black so as to see the geometry if it does turn out black. Black is a common color for geometry when lighting logic fails for some reason.

Also, don't mess with alpha blending until you get the basics working. It may inadvertently hide geometry that would otherwise be visible.


Thanks for your reply but it's just not happening. It's so frustrating as there's tons of examples on the internet and they do the exact same steps and they have the line.

I'm now testing in a stripped down version of the game, no background (plain grey), no lights, just two fixed 3d shapes and i'm trying to draw the line in the middle.

So I declare my D3DTLVERTEX to be
struct D3DTLVERTEX
{
float x, y, z, rhw;
DWORD color;
};

and then in the same function where the rest is rendered I've just put:

D3DTLVERTEX qV[4] = {
{ 0.0f, 0.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(248, 248, 255),},
{ 1.0f , 1.0f , 0.0f, 1.0f, D3DCOLOR_XRGB(248, 248, 255),},
{ 2.0f , 2.0f , 0.0f, 1.0f, D3DCOLOR_XRGB(248, 248, 255),},
{ 3.0f , 3.0f , 0.0f, 1.0f, D3DCOLOR_XRGB(248, 248, 255),},
};


device->DrawPrimitiveUP( D3DPT_LINESTRIP, 1, qV, sizeof( D3DTLVERTEX ) );





So I've added another two vertices since you said that with only two I'd only have one primitive of the line strip but still nothing will show up...

There's definitely nothing else to add to these lines to make this happen?

Or are there any alternative ways to draw 3d lines? Can ID3DXLine do it?

[Edited by - neo187 on December 5, 2010 2:48:53 PM]

Share this post


Link to post
Share on other sites
Ok in the end I got it up by using ID3DXLine::DrawTransform which takes an array of D3DXVECTOR3 and uses the transformation matrix to set it in space.

It looks kinda dull, I was somehow expecting it to have a bit mor "space" than a 2D ID3DXLine, but I guess that a line is just a line... Ok, a whole day of my life wasted on the wrong function.

But thanks all for the help!

Share this post


Link to post
Share on other sites
One primitive of a line strip is a line, which requires two vertices. Subsequent lines of the strip only require one vertex each, since each line uses the previous vertex as its start point.

Now, if you have only two vertices but you try to draw two primitives of a line strip, where does the data for the second line come from?

---

You need to call SetFVF method of the device interface in order to configure the input assembler of the device to match the actual format of the data you're feeding to it. The device cannot guess the structure of the vertices.

---

Your latest code (using DPUP) now only draws the first primitive of the line strip, but the dataset isn't very good for drawing anything. The x and y deltas between the two first vertices are only 1 pixel; since D3D doesn't (by default) draw the last pixel of lines, the line would effectively end up being invisible even though the act of drawing it would technically succeed.

---

D3DX interfaces are merely helper wrappers over the raw device functionality. If you can do something with D3DX, it is also possible in pure D3D (albeit usually with some more work).

Share this post


Link to post
Share on other sites

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