1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#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):
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+1];
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):
int PosX = trunc(X*Perspective);
int 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);//erros
th[i].join();
//NewSetPixel(ImageHDC, PosX,PosY,R,G,B);
}
//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(200,200);
int main()
{
img.DrawRectangle(0,100,0, 100,100,500, RGB(255,0,0),true);
BitBlt(GetWindowDC(GetConsoleWindow()),10,100,img.ImageWidth,img.ImageHeight,img.ImageHDC,0,0,SRCCOPY);
return 0;
}
|