Saturday, 9 February 2013

Assignment 2: Introduction to 3D

  • Requirements
    • Modify the Assignment 01 to draw a 3D box (instead of a 2D rectangle)
      • The box should have 8 vertices and 12 triangles
      • The box's vertices should only have positive or negative 1.0 for coordinates. For example, (-1, -1, -1) and (1, 1, 1).
    • The data for the box must still come from a Mesh file
      • Modify your file format to use 3D vertices
    • The data for the box must also have a color in addition to position
      • Modify your file format to include a color made up of three unsigned bytes
        • These three values still represent RGB values, but each one will be an integer value [0,255] instead of a floating point value [0,1].
      • Each vertex should use a different RGB value (this makes it easier to see the cube than using a solid color)
        • Your vertex shader can pass the vertex colors on unmodified to the fragment shader, and the fragment shader can output the interpolated color unmodified.
    • Your mesh should now use index buffers in addition to vertex buffers
      • Your vertex buffer should only have the 8 vertices that the box needs
      • The index buffer must contain enough indices to draw 12 triangles (3 * 12 = 36)
    • You must set create the following three matrices and pass them to the vertex shader:
      • Model to World
      • World to View
      • View to Projected
    • You must use each the matrices in the vertex shader to get a representation of the vertex in each of the three spaces. In other words, your vertex shader must have valid variables for each of the following:
      • The vertex's position in world space
      • The vertex's position in view space
      • The vertex's position in projected space
    • The box should be movable
      • Its initial position should be the origin (0, 0, 0), and it should have no rotation
        • In other words, it's model-to-world transformation should be the identity matrix
      • It should rotate around the Y axis at a constant speed
      • The user should be able to change its translation
        • Use UserInput::IsKeyPressed() or UserInput::IsButtonPressed() to get input from the user
        • REMEMBER TO DOCUMENT IN YOUR WRITEUP HOW TO MOVE THE BOX
    • The camera should be movable
      • It should start at (0, 0, -10), and be facing forwards towards the box (i.e. in the (0, 0, 1) direction)
      • The user should be able to change its position
        • Use UserInput::IsKeyPressed() or UserInput::IsButtonPressed() to get input from the user
        • REMEMBER TO DOCUMENT IN YOUR WRITEUP HOW TO MOVE THE CAMERA
    • Your writeup must include:
      • A screenshot of your colorful box
      • A screenshot from PIX showing the mesh data before the vertex shader is run and after the vertex shader is run
      • Instructions on how to move the camera and the box
    Details

    Vertex Format
    • To support 3D position, the vertex declaration should be updated to use D3DDECLTYPE_FLOAT3
    • The most correct way to represent an unsigned byte is to #include <cstdint> and using the type uint8_t. This is an unsigned integer type that is explicitly 8 bits regardless of platform
    • To update the vertex declaration to include the color:
      • Use D3DDECLTYPE_D3DCOLOR for the type
        • You can use the macro D3DCOLOR_XRGB() to convert your three bytes to a D3DCOLOR
      • Use D3DDECLUSAGE_COLOR for the usage
        • This means you will use the COLOR semantic as an input to your vertex shader. Assuming that you specify 0 for the index, the vertex shader would use "COLOR0" for its semantic
      • There will still only be a single stream of data, and so the stream index for the color element in the vertex declaration should still be 0 (just like it is for position). The offset into the stream must be changed, however. You need to tell DirectX how many bytes from the beginning of the vertex the color element starts. To do this, you need to figure out how many bytes position requires.
    Index Buffer
    • The order of vertices in each triangle is still critical even though an index buffer is used; make sure that each triangle is specified with a clockwise winding order
    Moving the box
    • Rotation around the Y axis
      • You may use D3DXMatrixRotationY() to calculate a rotation matrix from an angle, and you may use D3DXToRadian() to calculate an angle in radians
      • Use g_time.GetSecondsElapsedThisFrame() to ensure a constant rotational speed. (In other words, do not change the rotation by the same amount every frame, since the time elapsed between frames is not guaranteed to be constant. Instead, define how much the rotation should change each second, and then use that to calculate how much it should change in a given frame based on how many seconds have elapsed since the last frame.)
    • Translation
      • It is up to you to decide how the user controls the box's movement, but you may use any or all of the following suggestions
      • You may use D3DXMatrixTranslation() to create a translation matrix and then D3DXMatrixMultiply() to combine the translation with the rotation. Alternatively, you can add the translation to the rotation matrix yourself.
      • I advise using the arrow keys to move the box. Use UserInput::IsKeyPressed( VK_LEFT ) to find out if the left arrow key is pressed, and the analogous virtual key codes for the other arrow keys
        • Here is a list of all virtual key codes
      • I advise moving the box in the XY plane (in other words, left/right and up/down). If you prefer, though, you may move it in the XZ plane (in other words, left/right and forwards/backwards).
    Moving the camera
    • It is up to you to decide how the user controls the camera's movement, but you may use any or all of the following suggestions
    • The easiest way to calculate the world-to-view matrix is by using the function D3DXMatrixLookAtLH() so that the camera is always pointing at the origin or at the box. This is perfectly acceptable, but you may find that it's visually confusing since we are only drawing the box and nothing else (i.e. if we were also drawing a floor and walls it would help to understand what the camera is doing). An alternate solution is to not let the camera rotate, and use D3DXMatrixTranslation() with the camera's position negated.
    • I advise using the WASD keys to move the camera
    I advise moving the camera in the XY plane. If you prefer, though, you may move it in the XZ plane.

No comments:

Post a Comment