DX11 Learning Notes-4, using DX to draw a rotating cube

Source: Internet
Author: User
Tags create index mul

Continue to organize your knowledge according to MS's official tutorials. We have discussed the vertex transformation from the theoretical level, this one we will apply the theory to practice. The transformation of vertices in DX11 is also done in vertex shaders, so in addition to vertex information, we need to add the transformation matrix into the queue of shader input. Initializing transformation matrices

For ease of operation, we put three transformation matrices in a single structure body that will be used as a constant cache input shader.

struct Constantbuffer
{
    Xmmatrix mworld;
    Xmmatrix Mview;
    Xmmatrix mprojection;
};

Global Variables NEW:

id3d11buffer*           g_pconstantbuffer = NULL;
Xmmatrix                G_world;
Xmmatrix                G_view;
Xmmatrix                g_projection;

Initdevice () NEW:

/Create the constant buffer Bd.
    Usage = D3d11_usage_default; Bd.
    Bytewidth = sizeof (Constantbuffer); The binding information is a constant cache Bd.
    Bindflags = D3d11_bind_constant_buffer; Bd.
    cpuaccessflags = 0; 
    First pass the NULL data in, render update g_pconstantbuffer hr = G_pd3ddevice->createbuffer (&BD, NULL, &g_pconstantbuffer);

    if (FAILED (HR)) return to HR;

    Initializes each matrix//set model matrix, initializing//Initialize the world Matrix G_world = Xmmatrixidentity ();
    Sets the view matrix, initializes the camera position and faces///Initialize The view matrix xmvector Eye = Xmvectorset (0.0f, 1.0f, -5.0f, 0.0f);
    Xmvector at = Xmvectorset (0.0f, 1.0f, 0.0f, 0.0f);
    Xmvector up = Xmvectorset (0.0f, 1.0f, 0.0f, 0.0f);

    G_view = XMMATRIXLOOKATLH (Eye, at, up); Sets the perspective projection matrix, xm_pidiv2=1.57, is the radian value of the angle of view on the y-direction; width and height are the width height of the window client area//Initialize the projection matrix g_projection = XM MATRIXPERSPECTIVEFOVLH (Xm_pidiv2, Width/(FLOAT) height, 0.01f, 100.0f); 
the actual value of the input transformation matrix when rendering

When render (), we will update the G_pconstantbuffer fill data

    Constantbuffer CB;
    Cb.mworld = Xmmatrixtranspose (G_world);
    Cb.mview = Xmmatrixtranspose (G_view);
    Cb.mprojection = Xmmatrixtranspose (g_projection);
    Update constant cache Data
    G_pimmediatecontext->updatesubresource (g_pconstantbuffer, 0, NULL, &CB, 0, 0);

    Set the constant cache
    g_pimmediatecontext->vssetconstantbuffers (0, 1, &g_pconstantbuffer);
To set the matrix at the shader
    The global declaration
    //cbuffer (constant buffer) is the HLSL built-in type
    //register (B0), and the register description is the variable passed in by the application. B0 (BUFFER0) indicates that the variable needs to bind the first value of the incoming buffer array
    cbuffer constantbuffer:register (b0)
    {
        matrix world;
        Matrix View;
        Matrix projection;
    }
    The VS function adds code
    //MUL (matrix1,matrix2) is a HLSL built-in function, matrix1 and 2 cannot be reversed
    //Since DX is represented by a row vector, so the vector is in front of the transformation matrix.
    vs_output OUTPUT = (vs_output) 0;
    Output. pos = Mul (pos, world);
    Output. Pos = Mul (output. Pos, View);
    Output. Pos = Mul (output. Pos, projection);
    return output;
Draw a cube

The above shows how to pass data information other than the vertex to the shader.
To draw a rotating cube, we need to draw 6 square faces, which is 12 triangles. The constituent vertices of these 12 triangles coincide with each other, in fact we only need to use the 8 vertices repeatedly. Then, after defining 8 vertices, it is clear that we need an indexed array to indicate which vertices are needed to make up each triangle.
In addition, the global variable adds an index cache, and we add color information to the vertex structure. Since the vertex information of the input vertex shader has more color description, the input layout also needs to be modified.

New index cache global variable
id3d11buffer*           g_pindexbuffer = NULL;
struct Simplevertex
{
    XMFLOAT3 Pos;
    XMFLOAT4 Color;
};
Modify layout, add color element
d3d11_input_element_desc layout[] =
    {
        {"POSITION", 0, Dxgi_format_r32g32b32_float , 0, 0, d3d11_input_per_vertex_data, 0},
        {"COLOR", 0, dxgi_format_r32g32b32a32_float, 0, D3d11_input_per_vertex _data, 0},
    };
    Initdevice () Add code//vertex array/Create vertex buffer Simplevertex vertices[] = {{XMFLOAT3 (-1.0 F, 1.0f, -1.0f), XMFLOAT4 (0.0f, 0.0f, 1.0f, 1.0f)}, {XMFLOAT3 (1.0f, 1.0f, -1.0f), XMFLOAT4 (0.0f, 1.0f, 0.0 F, 1.0f)}, {XMFLOAT3 (1.0f, 1.0f, 1.0f), XMFLOAT4 (0.0f, 1.0f, 1.0f, 1.0f)}, {XMFLOAT3 ( -1.0f, 1.0f , 1.0f), XMFLOAT4 (1.0f, 0.0f, 0.0f, 1.0f)}, {XMFLOAT3 ( -1.0f, -1.0f, -1.0f), XMFLOAT4 (1.0f, 0.0f, 1.0f, 1.0 f)}, {XMFLOAT3 (1.0f, -1.0f, -1.0f), XMFLOAT4 (1.0f, 1.0f, 0.0f, 1.0f)}, {XMFLOAT3 (1.0f, -1.0f, 1. 0f), XMFLOAT4 (1.0f, 1.0f, 1.0f, 1.0f)}, {XMFLOAT3 ( -1.0f, -1.0f, 1.0f), XMFLOAT4 (0.0f, 0.0f, 0.0f, 1.0f)}
    ,
    };
    D3D11_BUFFER_DESC BD;
    ZeroMemory (&BD, sizeof (BD)); Bd.
    Usage = D3d11_usage_default; Bd.
    Bytewidth = sizeof (SIMPLEVERTEX) * 8; Bd.
    Bindflags = D3d11_bind_vertex_buffer; Bd.
    cpuaccessflags = 0;
  D3d11_subresource_data InitData;  ZeroMemory (&initdata, sizeof (InitData));
    Initdata.psysmem = vertices;
    hr = G_pd3ddevice->createbuffer (&BD, &initdata, &g_pvertexbuffer);

    if (FAILED (HR)) return to HR;
    Set vertex buffer UINT stride = sizeof (SIMPLEVERTEX);
    UINT offset = 0;

    G_pimmediatecontext->iasetvertexbuffers (0, 1, &g_pvertexbuffer, &stride, &offset);

        Indexed array//Create index buffer WORD indices[] = {3,1,0, 2,1,3, 0,5,4, 1,5,0, 3,4,7, 0,4,3, 1,6,5, 2,6,1, 2,7,6, 3,7,2, 6,4,5, 7,4,6
    ,
    }; Bd.
    Usage = D3d11_usage_default; Bd.        Bytewidth = sizeof (WORD) * 36; Vertices needed for triangles in a triangle list Bd.
    Bindflags = D3d11_bind_index_buffer; Bd.
    cpuaccessflags = 0;
    Initdata.psysmem = indices;
    hr = G_pd3ddevice->createbuffer (&BD, &initdata, &g_pindexbuffer); If(FAILED (HR)) return to HR; Set Index buffer G_pimmediatecontext->iasetindexbuffer (g_pindexbuffer, dxgi_format_r16_uint, 0);
Render () function, using drawindexed instead of the original draw method

Vertex shader where the vertex structure adds color information

struct Vs_output
{
    float4 pos:sv_position;
    FLOAT4 color:color0;
};
Vertex shader
vs_output VS (float4 pos:position, float4 color:color)
{
    Vs_output OUTPUT = (vs_output) 0;
    Output. pos = Mul (pos, world);
    Output. Pos = Mul (output. Pos, View);
    Output. Pos = Mul (output. Pos, projection);
    Give the color information
    output. color = color;
    return output;
}
Pixel shader
float4 PS (vs_output input): Sv_target
{return
    input. Color;
}
let the cube turn.

Now we have a colored cube, but it doesn't look so solid--because it's just perpendicular to our line of sight, which makes it look like a two-dimensional square. To make it look more solid, we might as well turn it around.
What needs to be explained is that in this example, the coordinates of each vertex are defined in the world coordinate system, the center of the cube coincides with the origin of the World coordinate system (you can also change the value, so that the two do not coincide), G_world initial is the unit matrix. So here g_world can be used directly as a three-dimensional transformation matrix, or directly with Xmmatrixrotationy (t), without regard to its original value.
The following code is within the render () function.

/Update Our time//static local variables are equivalent to global variables, only after the first initialization, and then accumulating until the application exits.
    static float t = 0.0f;
    if (G_drivertype = = d3d_driver_type_reference) {T + = (float) xm_pi * 0.0125f;
        else {static DWORD Dwtimestart = 0;
        DWORD dwtimecur = GetTickCount ();
        if (Dwtimestart = = 0) Dwtimestart = dwtimecur;
    In each frame, the time difference between the current and the start time is computed, divided by 1000 to find out how many seconds T = (dwtimecur-dwtimestart)/1000.0f; ////Animate the cube//rotation transformation of the matrix around the y-axis G_world = Xmmatrixrotationy (t); 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.