# Visual C++ & C++ Programming > C++ and WinAPI >  how use multithread with a loop?

## Cambalinho

how can i add these 'for' on a multithread?


```
for(int X=100, H=imgTexture.ImageHeight; X<1000; X++)        {
            if(Speed >1000) Speed=1;
            img.DrawLine3D({(float)X-Speed,100,(float)H-Speed},{(float)X-Speed,400,(float)H-Speed},0,imgTexture, H,0,false);
            H++;
        }
```

these loop depends on 'img' and 'imgTexture' and 'Speed'.
i can create a function void with these loop, but i don't understand how can i add it on multithread  :Frown:

----------


## VictorN

Why do you think you need a "multithread"?

----------


## 2kaud

The point that sticks out to me is why is the if statement within the loop as Speed doesn't change within the loop.



```
if(Speed >1000) Speed=1;

for (int X = 100, H = imgTexture.ImageHeight; X < 1000; ++X, ++H)
    img.DrawLine3D({(float)X - Speed, 100, (float)H-Speed}, {(float)X - Speed, 400, (float)H - Speed}, 0, imgTexture, H, 0, false);
```

If you need to convert this into multi-threaded, then consider turning it into a for-each with an execution policy and a function for the img.DrawLIne3D
https://en.cppreference.com/w/cpp/algorithm/for_each

You might want to consider having say 10 for-each iterations with the draw function being a loop.

----------


## Cambalinho

so true... i did a several questions on some forums. so sorry something..(some forums need more questions, they think that i can ask off-topic, but the problem is the same  :Frown:  )
but the big problem is: how can  i speed up my algorithm?
i lose more speed on loops. but heres a code with multitthread did by me:


```
#include <iostream>#include <thread>
#include <windows.h>
#include <math.h>


using namespace std;
class image
{
public:
    int ImageWidth = 0;
    int ImageHeight = 0;
    HDC ImageHDC = NULL;
    HBITMAP ImageBitmap;
    HBITMAP oldBit;
    BITMAP bmp;
    BITMAPINFO info;
    size_t pixelSize;
    size_t scanlineSize;
    size_t bitmapSize;
    void* p;
    LPBYTE Pixels;




    void Clear(COLORREF BackColor = RGB(0,0,0))
    {
        RECT rec{0,0,ImageWidth,ImageHeight};
        HBRUSH HB = CreateSolidBrush(BackColor);
        FillRect(ImageHDC,&rec,HB);
        DeleteObject(HB);
    }


    image(int Width, int Height, COLORREF BackColor=RGB(0,0,0))
    {
        ImageHDC = CreateCompatibleDC(NULL);
        ImageWidth = Width;
        ImageHeight =Height;


        ZeroMemory (&info, sizeof (BITMAPINFO));
        info.bmiHeader.biSize = sizeof(info.bmiHeader);
        info.bmiHeader.biWidth = ImageWidth;
        // pay attention to the sign, you most likely want a
        // top-down pixel array as it's easier to use
        info.bmiHeader.biHeight = -ImageHeight;
        info.bmiHeader.biPlanes = 1;
        info.bmiHeader.biBitCount = 32;
        info.bmiHeader.biCompression = BI_RGB;
        info.bmiHeader.biSizeImage = 0;
        info.bmiHeader.biXPelsPerMeter = 0;
        info.bmiHeader.biYPelsPerMeter = 0;
        info.bmiHeader.biClrUsed = 0;
        info.bmiHeader.biClrImportant = 0;


        // the following calculations work for 16/24/32 bits bitmaps
        // but assume a byte pixel array




        ImageBitmap = CreateDIBSection(ImageHDC, &info, DIB_RGB_COLORS, (LPVOID*)&Pixels, 0, 0);
        if(ImageBitmap ==NULL) cout << "no HBITMAP";
        if(SelectObject(ImageHDC, ImageBitmap)==NULL) cout << "error";
        pixelSize = info.bmiHeader.biBitCount / 8;
        // the + 3 ) & ~3 part is there to ensure that each
        // scan line is 4 byte aligned
        scanlineSize = (pixelSize * info.bmiHeader.biWidth + 3) & ~3;
        bitmapSize = bmp.bmHeight * scanlineSize;
        Clear(BackColor);
    }






    void NewSetPixel(HDC DestinationHDC, int X, int Y, BYTE RedColor, BYTE GreenColor, BYTE BlueColor)
    {
        size_t pixelOffset = (Y) *scanlineSize + (X) *pixelSize;
        Pixels[pixelOffset+2]=RedColor;
        Pixels[pixelOffset+1]=GreenColor;
        Pixels[pixelOffset+0]=BlueColor;
    }


    void DrawLine( float X0, float Y0, float Z0, float X1, float Y1, float Z1, COLORREF LineColor)
    {
        //Getting Line Distance(float results) coordenates and line:
        float DX = abs(X1 - X0);
        float DY = abs(Y1 - Y0);
        float DZ = abs(Z1 - Z0);
        float LineDistance =sqrt((DX * DX) + (DY * DY) + (DZ * DZ));




        //Getting the Steps incrementation(float results):
        float XSteps = DX/LineDistance;
        float YSteps = DY/LineDistance;
        float ZSteps = DZ/LineDistance;


        //Draw Line using the Steps\ Incrementation:
        float X = X0;
        float Y = Y0;
        float Z = Z0;
        BYTE R = GetRValue(LineColor);
        BYTE G = GetGValue(LineColor);
        BYTE B = GetBValue(LineColor);
        std::thread th[(int)LineDistance];
        int PosX;
        int PosY;


        for(int i =0; i <LineDistance; i++)
        {
            //For every steps we calculate the perspective:
            float EyeDistance = 500;
            //Avoiding division by zero:
            if(Z==0) Z=1;
            float Perspective = EyeDistance/(EyeDistance+Z);


            //The 3D to 2D convertion(i use 300 of eye distance, but we can change it):


            PosX = trunc(X*Perspective);
            PosY = trunc(Y*Perspective);
            if(Z>=0 && PosX<ImageWidth && PosX>=0 && PosY<ImageHeight && PosY>=0)
            {
                th[i] = std::thread(&image::NewSetPixel,this,ImageHDC, PosX,PosY,R,G,B);
                th[i].join();
                //NewSetPixel(ImageHDC, PosX,PosY,R,G,B); //more speed than my multithread
            }


            //Increment steps(integer results):
            X+=XSteps;
            Y+=YSteps;
            Z+=ZSteps;
        }
    }


    void DrawRectangle(float PosX, float PosY, float PosZ, float Width, float Height, float Depth, COLORREF Color = RGB(255,0,0), bool Filled = false)
    {
        DrawLine( PosX, PosY, PosZ,PosX + Width, PosY, PosZ + Depth, Color);
        DrawLine( PosX, PosY, PosZ, PosX, PosY + Height, PosZ, Color);
        DrawLine( PosX + Width, PosY, PosZ + Depth, PosX + Width, PosY+Height, PosZ + Depth, Color);
        DrawLine( PosX, PosY + Height, PosZ, PosX + Width, PosY + Height, PosZ + Depth, Color);
        if(Filled==true)
        {
            for(int i = 0; i<Height; i++)
                DrawLine( PosX, PosY + i, PosZ,PosX + Width, PosY +i, PosZ + Depth, Color);


        }
    }


    ~image()
    {
        SelectObject(ImageHDC, oldBit);
        DeleteObject(ImageBitmap);
        DeleteDC(ImageHDC);
    }


};


image img(400,600);


int main()
{
    int FramePerSecond=0;
    int Frames=0;
    RECT rec2 ={0,30,170,50};
    auto Start =GetTickCount();


    float PosX=0;
    float PosY =50;
    float PosZ =0;
    do
    {


        if(GetAsyncKeyState(VK_UP) & 0x8000)
        {
            PosZ--;
            PosX--;
            PosY--;


        }
        img.Clear();
        img.DrawRectangle(0,50,PosZ, 500,400,1000, RGB(255,0,0),true);
        string s="Frame Per Second: " + to_string(FramePerSecond);
        DrawText(img.ImageHDC,s.c_str(),-1, &rec2, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
        BitBlt(GetWindowDC(GetConsoleWindow()),10,100,img.ImageWidth,img.ImageHeight,img.ImageHDC,0,0,SRCCOPY);
        Frames++;
        auto Actual =GetTickCount();
        if((Actual-Start) >= 1000)
        {
            Start = GetTickCount();
            FramePerSecond =Frames;
            Frames=0;
        }
    }while(!(GetAsyncKeyState(VK_ESCAPE) & 0x8000));




    return 0;
}
```

now see the problem on  DrawLine() and NewSetPixel()... they loose too much speed.
"Process returned 0 (0x0)   execution time : 82.786 sPress any key to continue."
i learned the C\C++, by me: tutorials, books and forums and experience... what i mean is: we can make algorithms, but we don't learn how we can speed up... only learn, for exemple, the SetPixel() is much more slow than DIB's... but the loops and array's can be slow too... and i don't know how win speed. we can learn Multithread... but, like you see, is more slow.
without multithread, the same code, i get:
"Process returned 0 (0x0)   execution time : 0.109 sPress any key to continue."
but with 40FPS.. i only draw 1 rectangle with Z. imagine 10 rectangles... it will be too much slow.
i don't know how can i win more speed  :Frown:

----------

