diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index d296417..fa30195 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -6,106 +6,109 @@ #include namespace hgl { - template - static void FillPixels(T *p,const T &color,const int length) + namespace bitmap { - std::fill_n(p,length,color); - } - - /** - * 简单的2D象素处理 - */ - template class Bitmap - { - int width,height; - - T *data; - - public: - - Bitmap() + template + static void FillPixels(T *p,const T &color,const int length) { - data=nullptr; - width=height=0; + std::fill_n(p,length,color); } - ~Bitmap() + /** + * 简单的2D象素处理 + */ + template class Bitmap { - delete[] data; - } + int width,height; - const int GetWidth ()const{return width;} - const int GetHeight ()const{return height;} - const uint GetTotalPixels ()const{return width*height;} - const uint GetLineBytes ()const{return width*sizeof(T);} - const uint GetTotalBytes ()const{return width*height*sizeof(T);} + T *data; - T *GetData(){return data;} - T *GetData(int x,int y) - { - return (x<0||x>=width||y<0||y>=height)?nullptr:data+(y*width+x); - } + public: - bool Create(uint w,uint h) - { - if(!w||!h)return(false); - - if(data) + Bitmap() { - if(width==w&&height==h)return(true); + data=nullptr; + width=height=0; } - width=w; - height=h; - - delete[] data; - - data=new T[width*height]; - - return(true); - } - - void Clear() - { - if(data) + ~Bitmap() { delete[] data; - data=nullptr; } - width=height=0; - } + const int GetWidth ()const{return width;} + const int GetHeight ()const{return height;} + const uint GetTotalPixels ()const{return width*height;} + const uint GetLineBytes ()const{return width*sizeof(T);} + const uint GetTotalBytes ()const{return width*height*sizeof(T);} - void ClearColor(const T &color) - { - if(!data)return; - - FillPixels(data,color,width*height); - } - - void Flip() - { - if(!data||height<=1)return; - - const uint line_bytes=width*sizeof(T); - - T *temp=new T[width]; - - T *top=data; - T *bottom=data+(width*(height-1)); - - while(top=width||y<0||y>=height)?nullptr:data+(y*width+x); } - delete[] temp; - } - };//template class Bitmap + bool Create(uint w,uint h) + { + if(!w||!h)return(false); + + if(data) + { + if(width==w&&height==h)return(true); + } + + width=w; + height=h; + + delete[] data; + + data=new T[width*height]; + + return(true); + } + + void Clear() + { + if(data) + { + delete[] data; + data=nullptr; + } + + width=height=0; + } + + void ClearColor(const T &color) + { + if(!data)return; + + FillPixels(data,color,width*height); + } + + void Flip() + { + if(!data||height<=1)return; + + const uint line_bytes=width*sizeof(T); + + T *temp=new T[width]; + + T *top=data; + T *bottom=data+(width*(height-1)); + + while(top class Bitmap + }//namespace bitmap }//namespace hgl #endif//HGL_2D_BITMAP_INCLUDE diff --git a/inc/hgl/2d/Blend.h b/inc/hgl/2d/Blend.h new file mode 100644 index 0000000..eb6b5fe --- /dev/null +++ b/inc/hgl/2d/Blend.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +namespace hgl +{ + namespace bitmap + { + enum class BlendMode + { + NoBlend, ///< + Alpha, /// struct BlendColor + { + BlendMode mode=BlendMode::NoBlend; + + public: + + virtual const T &BlendNoBlend(const T &src,const T &dst,const float alpha) + { + return src; + } + + virtual const T &BlendAlpha(const T &src,const T &dst,const float alpha) + { + return src*alpha+dst*(1-alpha); + } + + virtual const T &BlendAdd(const T &src,const T &dst,const float alpha) + { + return src*alpha+dst; + } + + virtual const T &BlendSub(const T &src,const T &dst,const float alpha) + { + return src*alpha-dst; + } + + virtual const T &Blend(const T &src,const T &dst,const float alpha) + { + switch(mode) + { + case BlendMode::NoBlend: return BlendNoBlend(src,dst,alpha); + case BlendMode::Alpha: return BlendAlpha(src,dst,alpha); + case BlendMode::Add: return BlendAdd(src,dst,alpha); + case BlendMode::Sub: return BlendSub(src,dst,alpha); + } + + return src; + } + };//template class BlendColor + }//namespace bitmap +}//namespace hgl \ No newline at end of file diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h index 17b33e3..84aa1cd 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -1,154 +1,204 @@ #pragma once #include +#include #include namespace hgl { - template class DrawGeometry + namespace bitmap { - public: - - using FormatBitmap=Bitmap; - - protected: - - FormatBitmap *bitmap; - - T draw_color; - - public: - - DrawGeometry(FormatBitmap *fb) + template class DrawGeometry { - bitmap=fb; - } + public: - virtual ~DrawGeometry()=default; + using FormatBitmap=Bitmap; - virtual void SetDrawColor(const T &color) - { - draw_color=color; - } + protected: - bool GetPixel(int x,int y,T &color) - { - if(!data)return(false); + FormatBitmap *bitmap; - T *p=GetData(x,y); + T draw_color; + float alpha; - if(!p)return(false); + BlendColor *blend; - color=*p; + public: - return(true); - } - - bool PutPixel(int x,int y) - { - if(!bitmap)return(false); - - T *p=bitmap->GetData(x,y); - - if(!p)return(false); - - *p=draw_color; - - return(true); - } - - bool DrawHLine(int x,int y,int length) - { - if(!bitmap)return(false); - - const int width=bitmap->GetWidth(); - const int height=bitmap->GetHeight(); - - if(y<0||y>=height)return(false); - if(x>=width)return(false); - if(x<0){length+=x;x=0;} - if(x+length>width)length=width-x; - - if(length<=0)return(false); - - FillPixels(bitmap->GetData(x,y),draw_color,length); - - return(true); - } - - bool DrawBar(int l,int t,int w,int h) - { - if(!bitmap)return(false); - - const int width=bitmap->GetWidth(); - const int height=bitmap->GetHeight(); - - if(l>=width||t>=height)return(false); - - if(l<0){w+=l;l=0;} - if(t<0){h+=t;t=0;} - - if(l+w>width)w=width-l; - if(t+h>height)h=height-t; - - if(w<=0||h<=0)return(false); - - for(int y=t;y(bitmap->GetData(l,y),draw_color,w); - - return(true); - } - - bool DrawVLine(int x,int y,int length) - { - if(!bitmap)return(false); - - const int width=bitmap->GetWidth(); - const int height=bitmap->GetHeight(); - - if(x<0||x>=width)return(false); - if(y>=height)return(false); - if(y<0){length+=y;y=0;} - if(y+length>height)length=height-y; - - if(length<=0)return(false); - - const uint line_bytes=bitmap->GetLineBytes(); - T *p=bitmap->GetData(x,y); - - for(int i=0;i=0) + draw_color=color; + } + + void SetBlend(BlendColor *bc) + { + blend=bc; + } + + virtual void SetBlend(const BlendMode &mode) + { + blend->mode=mode; + } + + void CloseBlend() + { + blend->mode=BlendMode.NoBlend; + } + + void SetAlpha(const float &a) + { + alpha=a; + } + + bool GetPixel(int x,int y,T &color) + { + if(!data)return(false); + + T *p=GetData(x,y); + + if(!p)return(false); + + color=*p; + + return(true); + } + + bool PutPixel(int x,int y) + { + if(!bitmap)return(false); + + T *p=bitmap->GetData(x,y); + + if(!p)return(false); + + *p=blend->Blend(draw_color,*p,alpha); + + return(true); + } + + bool DrawHLine(int x,int y,int length) + { + if(!bitmap)return(false); + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(y<0||y>=height)return(false); + if(x>=width)return(false); + if(x<0){length+=x;x=0;} + if(x+length>width)length=width-x; + + if(length<=0)return(false); + + T *p=bitmap->GetData(x,y); + + for(int i=0;iBlend(draw_color,*p,alpha); + + return(true); + } + + bool DrawBar(int l,int t,int w,int h) + { + if(!bitmap)return(false); + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(l>=width||t>=height)return(false); + + if(l<0){w+=l;l=0;} + if(t<0){h+=t;t=0;} + + if(l+w>width)w=width-l; + if(t+h>height)h=height-t; + + if(w<=0||h<=0)return(false); + + T *p=bitmap->GetData(x,y); + + for(int y=t;yBlend(draw_color,*p,alpha); + + p+=width-w; + } + + return(true); + } + + bool DrawVLine(int x,int y,int length) + { + if(!bitmap)return(false); + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(x<0||x>=width)return(false); + if(y>=height)return(false); + if(y<0){length+=y;y=0;} + if(y+length>height)length=height-y; + + if(length<=0)return(false); + + const uint line_bytes=bitmap->GetLineBytes(); + T *p=bitmap->GetData(x,y); + + for(int i=0;iBlend(draw_color,*p,alpha); + p+=line_bytes; + } + + return(true); + } + + bool DrawWireCircle(int x0,int y0,int radius) + { + if(!bitmap)return(false); + + if(radius<=0)return(false); + + int tn; + int x,y; + int xmax; + + y=radius; + x=0; + xmax=int(radius*HGL_SIN_45); + tn=(1-radius*2); + + while(x<=xmax) + { + if(tn>=0) + { + tn+=(6+((x-y)<<2)); + y--; + } + else + tn+=((x<<2)+2); + + PutPixel(x0+y,y0+x); + PutPixel(x0+x,y0+y); + PutPixel(x0-x,y0+y); + PutPixel(x0-y,y0+x); + PutPixel(x0-y,y0-x); + PutPixel(x0-x,y0-y); + PutPixel(x0+x,y0-y); + PutPixel(x0+y,y0-x); + + x++; } - else - tn+=((x<<2)+2); PutPixel(x0+y,y0+x); PutPixel(x0+x,y0+y); @@ -159,251 +209,240 @@ namespace hgl PutPixel(x0+x,y0-y); PutPixel(x0+y,y0-x); - x++; + return(true); } - PutPixel(x0+y,y0+x); - PutPixel(x0+x,y0+y); - PutPixel(x0-x,y0+y); - PutPixel(x0-y,y0+x); - PutPixel(x0-y,y0-x); - PutPixel(x0-x,y0-y); - PutPixel(x0+x,y0-y); - PutPixel(x0+y,y0-x); - - return(true); - } - - bool DrawSolidCircle(int x,int y,int radius) - { - if(!bitmap)return(false); - - if(radius<=0)return(false); - - int x0=x-radius; - int y0=y-radius; - int x1=x+radius; - int y1=y+radius; - - const int width=bitmap->GetWidth(); - const int height=bitmap->GetHeight(); - - if(x0<0)x0=0; - if(y0<0)y0=0; - if(x1>=width)x1=width-1; - if(y1>=height)y1=height-1; - - if(x0>x1||y0>y1)return(false); - - int r2=radius*radius; - - for(int cy=y0;cy<=y1;cy++) + bool DrawSolidCircle(int x,int y,int radius) { - int dy=cy-y; - int dy2=dy*dy; + if(!bitmap)return(false); - for(int cx=x0;cx<=x1;cx++) + if(radius<=0)return(false); + + int x0=x-radius; + int y0=y-radius; + int x1=x+radius; + int y1=y+radius; + + const int width=bitmap->GetWidth(); + const int height=bitmap->GetHeight(); + + if(x0<0)x0=0; + if(y0<0)y0=0; + if(x1>=width)x1=width-1; + if(y1>=height)y1=height-1; + + if(x0>x1||y0>y1)return(false); + + int r2=radius*radius; + + for(int cy=y0;cy<=y1;cy++) { - int dx=cx-x; - int dx2=dx*dx; + int dy=cy-y; + int dy2=dy*dy; - if(dx2+dy2<=r2) - PutPixel(cx,cy); - } - } - - return(true); - } - - void DrawLine(int x1, int y1, int x2, int y2) - { - int p, n, x, y, tn; - - if(y1==y2) - { - if(x1>x2) - { - x=x2;x2=x1;x1=x; - } - - DrawHLine(x1, y1, x2-x1+1); - return; - } - - if(x1==x2) - { - if(y1>y2) - { - y=y2;y2=y1;y1=y; - } - - DrawVLine(x1, y1, y2-y1+1); - return; - } - - if(abs(y2-y1)<=abs(x2-x1)) - { - if((y2x2)) - { - x=x2;y=y2;x2=x1;y2=y1;x1=x;y1=y; - } - - if(y2>=y1&&x2>=x1) - { - x=x2-x1;y=y2-y1; - p=2*y;n=2*x-2*y;tn=x; - - while(x1<=x2) + for(int cx=x0;cx<=x1;cx++) { - if(tn>=0)tn-=p; - else { tn+=n;y1++; } + int dx=cx-x; + int dx2=dx*dx; - PutPixel(x1++, y1); + if(dx2+dy2<=r2) + PutPixel(cx,cy); + } + } + + return(true); + } + + void DrawLine(int x1, int y1, int x2, int y2) + { + int p, n, x, y, tn; + + if(y1==y2) + { + if(x1>x2) + { + x=x2;x2=x1;x1=x; + } + + DrawHLine(x1, y1, x2-x1+1); + return; + } + + if(x1==x2) + { + if(y1>y2) + { + y=y2;y2=y1;y1=y; + } + + DrawVLine(x1, y1, y2-y1+1); + return; + } + + if(abs(y2-y1)<=abs(x2-x1)) + { + if((y2x2)) + { + x=x2;y=y2;x2=x1;y2=y1;x1=x;y1=y; + } + + if(y2>=y1&&x2>=x1) + { + x=x2-x1;y=y2-y1; + p=2*y;n=2*x-2*y;tn=x; + + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1++; } + + PutPixel(x1++, y1); + } + } + else + { + x=x2-x1;y=y2-y1; + p=-2*y;n=2*x+2*y;tn=x; + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1--; } + + PutPixel(x1++, y1); + } } } else { - x=x2-x1;y=y2-y1; - p=-2*y;n=2*x+2*y;tn=x; - while(x1<=x2) - { - if(tn>=0)tn-=p; - else { tn+=n;y1--; } + x=x1;x1=y2;y2=x;y=y1;y1=x2;x2=y; - PutPixel(x1++, y1); + if((y2x2)) + { + x=x2;y=y2;x2=x1;y2=y1;x1=x;y1=y; + } + + if(y2>=y1&&x2>=x1) + { + x=x2-x1;y=y2-y1;p=2*y;n=2*x-2*y;tn=x; + + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1++; } + + PutPixel(y1, x1++); + } + } + else + { + x=x2-x1;y=y2-y1;p=-2*y;n=2*x+2*y;tn=x; + + while(x1<=x2) + { + if(tn>=0)tn-=p; + else { tn+=n;y1--; } + + PutPixel(y1, x1++); + } } } } - else + + void DrawSector(int x0, int y0, uint r, uint stangle, uint endangle) { - x=x1;x1=y2;y2=x;y=y1;y1=x2;x2=y; + int i, j; + int *xy; + int bx, ex, bxd, exd, bxf, exf, ben; + int tn, x, y; + int xmax; - if((y2x2)) + y=r; x=0; + xmax=(int)(r*HGL_SIN_45); + tn=(1-r*2); + + xy=(int *)calloc(20, sizeof(int)); + xy[0]=x0+r;xy[1]=y0; + xy[2]=x0; xy[3]=y0-r; + xy[4]=x0; xy[5]=y0-r; + xy[6]=x0-r;xy[7]=y0; + xy[8]=x0-r;xy[9]=y0; + xy[10]=x0; xy[11]=y0+r; + xy[12]=x0; xy[13]=y0+r; + xy[14]=x0+r;xy[15]=y0; + + bx=stangle/45; + ex=endangle/45; + ben=ex-bx-1; + + xy[16]=(int)(r*Lcos(stangle)); + xy[17]=(int)(r*Lsin(stangle)); + xy[18]=(int)(r*Lcos(endangle)); + xy[19]=(int)(r*Lsin(endangle)); + + DrawLine(x0+xy[16], y0-xy[17], x0, y0); + DrawLine(x0+xy[18], y0-xy[19], x0, y0); + + if(bx==1||bx==2||bx==5||bx==6)bxd=abs(xy[16]);else bxd=abs(xy[17]); + if(ex==1||ex==2||ex==5||ex==6)exd=abs(xy[18]);else exd=abs(xy[19]); + if(bx==0||bx==2||bx==4||bx==6)bxf=0; else bxf=1; + if(ex==0||ex==2||ex==4||ex==6)exf=1; else exf=0; + + while(x<=xmax) { - x=x2;y=y2;x2=x1;y2=y1;x1=x;y1=y; - } - - if(y2>=y1&&x2>=x1) - { - x=x2-x1;y=y2-y1;p=2*y;n=2*x-2*y;tn=x; - - while(x1<=x2) + if(tn>=0) { - if(tn>=0)tn-=p; - else { tn+=n;y1++; } - - PutPixel(y1, x1++); + tn+=(6+((x-y)*4)); + y--; + xy[0]--; + xy[3]++; + xy[5]++; + xy[6]++; + xy[8]++; + xy[11]--; + xy[13]--; + xy[14]--; } - } - else - { - x=x2-x1;y=y2-y1;p=-2*y;n=2*x+2*y;tn=x; + else tn+=((x*4)+2); - while(x1<=x2) + if(stangle=0)tn-=p; - else { tn+=n;y1--; } - - PutPixel(y1, x1++); + j=(bx+1)*2; + for(i=0;iendangle) + { + j=(bx+1)*2; + for(i=bx+1;i<8;i++) + { + PutPixel(xy[j], xy[j+1]); + j+=2; + } + j=0; + for(i=0;ibxd)^bxf)PutPixel(xy[i], xy[i+1]);i=ex*2; + if((x>exd)^exf)PutPixel(xy[i], xy[i+1]);x++; + xy[1]--; + xy[2]++; + xy[4]--; + xy[7]--; + xy[9]++; + xy[10]--; + xy[12]++; + xy[15]++; } + free(xy); } - } - - void DrawSector(int x0, int y0, uint r, uint stangle, uint endangle) - { - int i, j; - int *xy; - int bx, ex, bxd, exd, bxf, exf, ben; - int tn, x, y; - int xmax; - - y=r; x=0; - xmax=(int)(r*HGL_SIN_45); - tn=(1-r*2); - - xy=(int *)calloc(20, sizeof(int)); - xy[0]=x0+r;xy[1]=y0; - xy[2]=x0; xy[3]=y0-r; - xy[4]=x0; xy[5]=y0-r; - xy[6]=x0-r;xy[7]=y0; - xy[8]=x0-r;xy[9]=y0; - xy[10]=x0; xy[11]=y0+r; - xy[12]=x0; xy[13]=y0+r; - xy[14]=x0+r;xy[15]=y0; - - bx=stangle/45; - ex=endangle/45; - ben=ex-bx-1; - - xy[16]=(int)(r*Lcos(stangle)); - xy[17]=(int)(r*Lsin(stangle)); - xy[18]=(int)(r*Lcos(endangle)); - xy[19]=(int)(r*Lsin(endangle)); - - DrawLine(x0+xy[16], y0-xy[17], x0, y0); - DrawLine(x0+xy[18], y0-xy[19], x0, y0); - - if(bx==1||bx==2||bx==5||bx==6)bxd=abs(xy[16]);else bxd=abs(xy[17]); - if(ex==1||ex==2||ex==5||ex==6)exd=abs(xy[18]);else exd=abs(xy[19]); - if(bx==0||bx==2||bx==4||bx==6)bxf=0; else bxf=1; - if(ex==0||ex==2||ex==4||ex==6)exf=1; else exf=0; - - while(x<=xmax) - { - if(tn>=0) - { - tn+=(6+((x-y)*4)); - y--; - xy[0]--; - xy[3]++; - xy[5]++; - xy[6]++; - xy[8]++; - xy[11]--; - xy[13]--; - xy[14]--; - } - else tn+=((x*4)+2); - - if(stangleendangle) - { - j=(bx+1)*2; - for(i=bx+1;i<8;i++) - { - PutPixel(xy[j], xy[j+1]); - j+=2; - } - j=0; - for(i=0;ibxd)^bxf)PutPixel(xy[i], xy[i+1]);i=ex*2; - if((x>exd)^exf)PutPixel(xy[i], xy[i+1]);x++; - xy[1]--; - xy[2]++; - xy[4]--; - xy[7]--; - xy[9]++; - xy[10]--; - xy[12]++; - xy[15]++; - } - free(xy); - } - };//template class DrawGeometry + };//template class DrawGeometry + }//namespace bitmap }//namespace hgl