Lines

Introduction

Message Handling

Drawing Lines

Lesson Downloads

Introduction

The basic primitive types are points, lines and triangles. With points taken care of in the previous lesson, we're moving on to lines. We're still using Screen Space coordinates and we're going to use the same data sets as we did in the Points lesson. When you see how few changes we had to make for this lesson you'll see how similar the different primitives are.

I also made a slight change in the message handling. I added back in the code to exit the app when the Escape key is hit.

Message Handling

As I mentioned before, you can use WM_CHAR to get printable, locale-correct characters as input while still using WM_KEYDOWN to get messages for non-printables like the arrow keys and Escape. All it took was the addition of another case in our switch. Since it's not very big, here's the code for that entire function.

LRESULT CALLBACK default_window_proc(HWND p_hwnd,UINT p_msg,WPARAM p_wparam,LPARAM p_lparam){
   
   switch(p_msg){
      case WM_CHAR:  // A key has been pressed, process the key

         if (p_wparam=='t') {
            random_mode=!random_mode;
         }
         return 0;
      case WM_KEYDOWN:
         if(p_wparam == VK_ESCAPE){ //User hit Escape, end the app

            g_app_done=true;
         }
         return 0;
      case WM_CLOSE:       //User hit the Close Window button, end the app

      case WM_LBUTTONDOWN: //user hit the left mouse button

         g_app_done=true;
         return 0;
   }
   
   return (DefWindowProc(p_hwnd,p_msg,p_wparam,p_lparam));
   
}

That's it. One thing to note is that when a WM_KEYDOWN is translated to a WM_CHAR a new WM_CHAR message is sent in addition to the original WM_KEYDOWN. So you if have a handler set to receive messages from 't' as a WM_CHAR and as a WM_KEYDOWN, you'll get 2 messages.

Drawing Lines

As I mentioned above, very few changes were required to convert the Points lesson to use lines. Additionally, this lesson will show both Line Lists and Line Strips. The random data set will be used to render the Line Lists and the sine data will be used on the Line Strips. Here's the Draw call for the random data.

   g_d3d_device->DrawPrimitiveUP(D3DPT_LINELIST,         //PrimitiveType

                                 g_width/2,              //PrimitiveCount

                                 random_data,            //pVertexStreamZeroData

                                 sizeof(line_vertex));   //VertexStreamZeroStride

Our PrimitiveType is D3DPT_LINELIST. Though we are using the same number of vertices as the Points sample, our PrimitiveCount is different. Each line takes up 2 vertices, so the number of primitives is equal to half the number of vertices. Other than the fact that I renamed the vertex structure to line_vertex, nothing else here has changed.

Line Strips are connected lines. The first 2 vertices form the first line and then each additional line adds a line using the previous vertex. By drawing our sine data with a line strip, we get a smooth continuous wave.

   g_d3d_device->DrawPrimitiveUP(D3DPT_LINESTRIP,        //PrimitiveType

                                 g_width-1,              //PrimitiveCount

                                 sine_data,              //pVertexStreamZeroData

                                 sizeof(line_vertex));   //VertexStreamZeroStride

The change to the PrimitiveType is obvious. The only other thing that's different is the PrimitiveCount. Each additional vertex adds one line strip, but the first line is made up of 2 vertices. So our PrimitiveCount is 1 less than the total number of vertices.

Lesson Downloads

Back