+ Reply to Thread
Page 6 of 7 FirstFirst ... 4 5 6 7 LastLast
Results 51 to 60 of 61

Thread: Where to render

  1. #51
    Join Date
    Mar 2005
    Location
    California
    Posts
    2,099

    Default

    An object is anything in your scene that can be moved independently of any other object.

    E.G. a tree would be an object. If you had a forest, you have a bunch of tree objects.

    An object is defined by a set of vertices (though one set of vertices can be shared among lots of different object, the forest being a good example of this), a world matrix (every object gets its own), and usually a material (i.e. a shader), though again, that material can be shared.

    In your scene, the rotating triangle is definitely its own object. I don't know what else you have in your scene. If there is something in the center of your circle, then that would also be an object.

    One other thing to keep in mind, Pix. Matrix multiplication is not communitive. So when you are building your world matrix for your object, keep the orders correct.

    Your world matrix will consist of a rotation, and then a translation. In that order.

    You can visualize this easy enough. If you rotate first, you are rotating around the origin. You then translate that rotated object to its correct location in space.

    Now try it the other way. First translate. That puts you in the right place. Now rotate. Since rotation is relative to the origin, the rotation will end up moving the entire triangle (in a circle). But you already had it where you wanted it, so this is clearly not correct.

    So, build two matrices (a rotation and a translation), and then multiply them together as W(r) * W(t), and that resulting matrix will give you your proper world matrix.

    [In actual fact, the translation parts of a world matrix are on the bottom row as values 0, 1 and 2, while the rotation parts are in the first three row, so they don't really interact, you could just put together the matrix manually rather than worry about multiplying them together. But it's probably better to do it correctly, because if you get into anything more complicated, like rotation around multiple axes, or scaling, you will definitely need to build individual matrices and multiply them together to get a final world matrix].
    Last edited by RonHiler; 09-08-2010 at 08:39 AM.
    "They laughed when I said I was going to be a comedian ... They're not laughing now." - Bob Monkhouse

  2. #52
    Join Date
    May 2005
    Posts
    390

    Default

    Quote Originally Posted by RonHiler View Post
    An object is anything in your scene that can be moved independently of any other object.

    E.G. a tree would be an object. If you had a forest, you have a bunch of tree objects.

    An object is defined by a set of vertices (though one set of vertices can be shared among lots of different object, the forest being a good example of this), a world matrix (every object gets its own), and usually a material (i.e. a shader), though again, that material can be shared.
    Ok, but is there anything in DirectX (or OpenGL, hypothetically speaking) that formally defines an object, or is it just something you kind of have to remember? I haven't looked much beyond drawing small sets of triangles yet, but I don't recall anything like a BeginObject/EndObject pair, or a DefineObject function that takes a vertex buffer, for example.

    I can see how it could make sense for a model of, say, a person or a mech to be made up of a series of objects, one for each piece that has independent movement. That would let you do things like make the arm (or even upper arm) an object, so that you could make the shoulder joint's point of rotation be located on the origin, for ease of calculation. But a plain old vertex buffer couldn't really be an object as such, because I could use the same buffer to be "the left arm of every person in the world."

    So let's keep it simple. Let's say I have two vertex buffers, each representing a different Pythagorean solid (so there's no confusion engendered by using the same buffer to represent two icosahedrons, for example.) If I want them to be two objects, I would, for each of them, create the buffer, create and manipulate a world matrix, do anything else necessary, and then call DrawPrimitive, and all of that would be wrapped in a BeginScene/EndScene pair (and of course any overall setup like the shaders)?

  3. #53
    Join Date
    Mar 2005
    Location
    California
    Posts
    2,099

    Default

    Quote Originally Posted by Pix View Post
    Ok, but is there anything in DirectX (or OpenGL, hypothetically speaking) that formally defines an object, or is it just something you kind of have to remember? I haven't looked much beyond drawing small sets of triangles yet, but I don't recall anything like a BeginObject/EndObject pair, or a DefineObject function that takes a vertex buffer, for example.
    No. You have to keep track of "objects" yourself. The object would be an instance of a class, and that class would contain a vertex buffer (or an index to a generic vertex buffer), a world matrix, and a material reference.

    Just before you draw each object (via Draw() or DrawIndexed()) is when you bind the vertex buffer to the GPU (IASetVertexBuffers), send the matrix to the shader, and set the shader itself.

    So in that respect, you draw one "object" for each Draw() call.

    So let's keep it simple. Let's say I have two vertex buffers, each representing a different Pythagorean solid (so there's no confusion engendered by using the same buffer to represent two icosahedrons, for example.) If I want them to be two objects, I would, for each of them, create the buffer, create and manipulate a world matrix, do anything else necessary, and then call DrawPrimitive, and all of that would be wrapped in a BeginScene/EndScene pair (and of course any overall setup like the shaders)?
    Well, sort of. I don't know the DrawPrimiitive() call, but I presume it is analogous to Draw() or DrawIndexed().

    This part:
    "create the buffer, create and manipulate a world matrix"
    Don't wrap that in your Begin/End scene pairs. Do that stuff in advance, and only bind it to the GPU when you get into the scene. You want to do as little as possible inside the scene itself. Bind *existing* buffers to the GPU, don't recreate them with every draw call.
    "They laughed when I said I was going to be a comedian ... They're not laughing now." - Bob Monkhouse

  4. #54
    Join Date
    May 2005
    Posts
    390

    Default

    "You have to keep track of "objects" yourself."

    Ok, that's what I thought.

    "I don't know the DrawPrimiitive() call, but I presume it is analogous to Draw() or DrawIndexed()."

    Yep, it's a DX9 call.

    If I'm using the FVF pipeline for now, and I start with untransformed vertices, and I set up my transforms, when I call a draw function, does it take care of everything or do I have to call ProcessVertices or something? I have a buffer, and I set some transforms, and draw it. Then I set up a new set of transforms, including a rotation, and when I draw it again, it appears in a different place, but it isn't rotated, so I'm still not doing something right.

    I'm pretty sure it's a Z-rotation I want, right? My triangles are parallel to the XY plane, so a Z-rotation of PI radians should make a triangle that started out pointing down (relative to the XY plane) wind up pointing up, right?

  5. #55
    Join Date
    Mar 2005
    Location
    California
    Posts
    2,099

    Default

    [quote=Pix;2799If I'm using the FVF pipeline for now, and I start with untransformed vertices, and I set up my transforms, when I call a draw function, does it take care of everything or do I have to call ProcessVertices or something? [/quote]
    No, I think all you have to do is send in your matrices and call your DrawPrimitive() call. There is no process vertices or anything. At least I think not. As I said before, I don't remember the fixed function pipeline all that well.

    I have a buffer, and I set some transforms, and draw it. Then I set up a new set of transforms, including a rotation, and when I draw it again, it appears in a different place, but it isn't rotated, so I'm still not doing something right.
    How are you creating your transform matrix?

    I'm pretty sure it's a Z-rotation I want, right? My triangles are parallel to the XY plane, so a Z-rotation of PI radians should make a triangle that started out pointing down (relative to the XY plane) wind up pointing up, right?
    Yes, this is correct, assuming that the model origin is centered in the triangle.
    "They laughed when I said I was going to be a comedian ... They're not laughing now." - Bob Monkhouse

  6. #56
    Join Date
    May 2005
    Posts
    390

    Default

    Code:
    struct CUSTOMVERTEX
    {
        FLOAT x, y, z;
        DWORD color;
    };
    
    CUSTOMVERTEX v1[] =
    {
        { -10,  17, 0.5f, 0xffff8000 },
        {  10,  17, 0.5f, 0xffff8000 },
        {   0,   0, 0.5f, 0xffff0000 },
        {  20,   0, 0.5f, 0xff00ff00 },
    
        {  10, -17, 0.5f, 0xff0000ff },
        { -10, -17, 0.5f, 0xffff00ff },
        { -20,   0, 0.5f, 0xffff00ff },
    };
    
        FLOAT angle = 0;
    
        pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
        pDevice->BeginScene();
        pDevice->SetStreamSource(0, pVB, 0, sizeof(CUSTOMVERTEX));
        pDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
    
        D3DXMatrixIdentity(&temp);
        D3DXMatrixRotationZ(&temp, angle);
        D3DXMatrixTranslation(&temp, 0, 100, 0);
    
        D3DXVECTOR3 eye(0, 0, -5);
        D3DXVECTOR3 at(0, 0, 0);
        D3DXVECTOR3 up(0, 1, 0);
        D3DXMatrixLookAtLH(&view, &eye, &at, &up);
    
        D3DXMatrixMultiply(&world, &temp, &view);
        D3DXMatrixIdentity(&view);
        D3DXMatrixPerspectiveLH(&proj, 80, 60, 1, -10);
    
        pDevice->SetTransform(D3DTS_WORLDMATRIX(0), &world);
        pDevice->SetTransform(D3DTS_VIEW, &view);
        pDevice->SetTransform(D3DTS_PROJECTION, &proj);
    
        pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);
    
        D3DXMatrixIdentity(&temp);
        D3DXMatrixRotationZ(&temp, D3DX_PI);
        D3DXMatrixTranslation(&temp, 50, -100, 0);
        D3DXMatrixIdentity(&view);
        D3DXMatrixLookAtLH(&view, &eye, &at, &up);
        D3DXMatrixMultiply(&world, &temp, &view);
    
        pDevice->SetTransform(D3DTS_WORLDMATRIX(0), &world);
    
        pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);
    I was playing with this a bit so it might be slightly messed up.

    This draws two triangles, point down. The bottom one, in the second set of calls, is correctly offset in X and Y, but it stubbornly refuses to rotate. I'm sure at this point I'm missing something obvious.

    DrawPrimitive apparently doesn't exist in DX10+. It just operates on the vertex buffer you've already attached. In this case, it takes the first three vertices in the buffer I've defined, and treats them as a triangle.

  7. #57
    Join Date
    Mar 2005
    Location
    California
    Posts
    2,099

    Default

    Here's your problem, I think:

    D3DXMatrixIdentity(&temp);
    D3DXMatrixRotationZ(&temp, angle);
    D3DXMatrixTranslation(&temp, 0, 100, 0);
    The D3DX functions there don't combine matrices. What you've done here is created an identity matrix, then replaced it with a rotation matrix, then replaced that with your translation matrix. This is why you are not seeing a rotation, because you erased it.

    Try this:
    D3DXMatrixRotationZ(&RotMatrix, angle);
    D3DXMatrixTranslation(&TransMatrix, 0, 100, 0);
    D3DXMatrixMultiply(&WorldMatrix, &RotMatrix, &TransMatrix);

    Note that the order in the last call is important. That gives you a combined rotation/translation matrix which is your world matrix for that object.

    I think that will get you where you want.

    I also don't really grek what you are doing with the "world" matrix in this bit of code:

    D3DXMatrixMultiply(&world, &temp, &view);
    D3DXMatrixIdentity(&view);
    D3DXMatrixPerspectiveLH(&proj, 80, 60, 1, -10);

    pDevice->SetTransform(D3DTS_WORLDMATRIX(0), &world);
    pDevice->SetTransform(D3DTS_VIEW, &view);
    pDevice->SetTransform(D3DTS_PROJECTION, &proj);
    It looks like you are creating a world matrix (temp), then combining a view matrix (view) with it (into what you are erroneously calling "world"), then setting your view matrix to identity. While that isn't exactly wrong (it'll work), you are doing extra steps on the CPU that will be handled by the GPU. There is no reason to pre-combine the combined world/view matrix, the pipeline is going to do that anyway, so you are just wasting cycles.

    Everything else looks right. I like your view and projection matrices. I suspect when you make that one change, you will get the correct behavior.

    One last thing to note, your square has a vertex on the (0,0,z) mark. When you rotate around the z axis, that will be your pivot point (rather than the center of the square). You probably already know that, but just in case....
    Last edited by RonHiler; 09-13-2010 at 12:57 PM.
    "They laughed when I said I was going to be a comedian ... They're not laughing now." - Bob Monkhouse

  8. #58
    Join Date
    May 2005
    Posts
    390

    Default

    Quote Originally Posted by RonHiler View Post
    Here's your problem, I think:

    The D3DX functions there don't combine matrices. What you've done here is created an identity matrix, then replaced it with a rotation matrix, then replaced that with your translation matrix. This is why you are not seeing a rotation, because you erased it.
    Try this:
    D3DXMatrixRotationZ(&RotMatrix, angle);
    D3DXMatrixTranslation(&TransMatrix, 0, 100, 0);
    D3DXMatrixMultiply(&WorldMatrix, &RotMatrix, &TransMatrix);

    Note that the order in the last call is important. That gives you a combined rotation/translation matrix which is your world matrix for that object.
    I bet you the problem is I seem to have forgotten the matrix multiply.

    I think that will get you where you want.

    I also don't really grek what you are doing with the "world" matrix in this bit of code:



    It looks like you are creating a world matrix (temp), then combining a view matrix (view) with it (into what you are erroneously calling "world"), then setting your view matrix to identity. While that isn't exactly wrong (it'll work), you are doing extra steps on the CPU that will be handled by the GPU. There is no reason to pre-combine the combined world/view matrix, the pipeline is going to do that anyway, so you are just wasting cycles.
    The DX SDK says that lots of transforms of the world and view matrices carries a performance penalty, so it makes sense to multiply the two and use the combined matrix as the world matrix, and set the view matrix to the identity matrix. That's what I was trying to do.

    Everything else looks right. I like your view and projection matrices. I suspect when you make that one change, you will get the correct behavior.

    One last thing to note, your square has a vertex on the (0,0,z) mark. When you rotate around the z axis, that will be your pivot point (rather than the center of the square). You probably already know that, but just in case....
    Yeah, that's what I wanted, but thanks for point it out. I'd've been perturbed if what I'd intended was to rotate around the triangle's center.

    And it works! I get my two triangles, pointing towards each other! Now I just need to put back in the animation. Thanks for the help.

  9. #59
    Join Date
    Mar 2005
    Location
    California
    Posts
    2,099

    Default

    Quote Originally Posted by Pix View Post
    The DX SDK says that lots of transforms of the world and view matrices carries a performance penalty, so it makes sense to multiply the two and use the combined matrix as the world matrix, and set the view matrix to the identity matrix. That's what I was trying to do.
    Huh. I'm not sure what the docs are trying to get at here. A matrix multiply is just a matrix multiply. There isn't going to be any difference in performance if you multiply two very complex matrices together than if you multiply two identity matrices. So I don't really understand what they are trying to accomplish.

    The GPU is always going to multiply the world and view matrices together (that's part of the "Fixed" in fixed function pipeline). That is why you have to supply a view matrix (even if it's just identity). So what you've done is multiply together two matrices on the CPU, then sent two more matrices together to be multiplied on the GPU. Twice the work.

    But okay. Certainly I'm no expert on the internal workings of the DirectX API, so maybe they know something I don't.

    And it works! I get my two triangles, pointing towards each other! Now I just need to put back in the animation. Thanks for the help.
    Cool. Good to hear. It's always good to get your first triangles on the screen. That's at least half the battle
    "They laughed when I said I was going to be a comedian ... They're not laughing now." - Bob Monkhouse

  10. #60
    Join Date
    May 2005
    Posts
    390

    Default

    I'm not sure what the docs are trying to get at here.
    World Transform (Direct3D 9) says
    Note Direct3D uses the world and view matrices that you set to configure several internal data structures. Each time you set a new world or view matrix, the system recalculates the associated internal structures. Setting these matrices frequently-for example, thousands of times per frame-is computationally time-consuming. You can minimize the number of required calculations by concatenating your world and view matrices into a world-view matrix that you set as the world matrix, and then setting the view matrix to the identity. Keep cached copies of individual world and view matrices so that you can modify, concatenate, and reset the world matrix as needed. For clarity, in this documentation Direct3D samples rarely employ this optimization.
    It's always good to get your first triangles on the screen.
    Yep. I actually had triangles up for a week, then took a break. Then I got hung up getting the transforms right.

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts