From 692c41360205e7e9a5ea244cf07f15aa2478c85a Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Wed, 5 Jul 2023 17:23:32 +0800 Subject: [PATCH 01/16] add codes of Bitmap.h --- inc/hgl/2d/Bitmap.h | 170 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 2 deletions(-) diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index 7161131..2e2fdd2 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -1,13 +1,179 @@ #ifndef HGL_2D_BITMAP_INCLUDE #define HGL_2D_BITMAP_INCLUDE +#include +#include namespace hgl { /** * 简单的2D象素处理 */ - template class Bitmap2D + template class Bitmap { - };// + uint width,height; + + T *data; + + public: + + Bitmap() + { + data=nullptr; + width=height=0; + } + + ~Bitmap() + { + delete[] data; + } + + 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*CHANNELS]; + + return(true); + } + + void Clear() + { + if(data) + { + delete[] data; + data=nullptr; + } + + width=height=0; + } + + void ClearColor(T *color) + { + if(!data||!color)return; + + uint total=width*height; + + T *p=data; + + for(size_t i=0; i *outputs) + { + if(!data||!outputs) + return(false); + + T *sp=data; + AutoDeleteArray op=new T *[CHANNELS]; + + for(uint i=0;i *inputs) + { + if(!data||!inputs) + return(false); + + T *dp=data; + AutoDeleteArray ip=new T *[CHANNELS]; + + for(uint i=0;i class Bitmap + + using BitmapR8 =Bitmap; + using BitmapR16 =Bitmap; + using BitmapR32U =Bitmap; + using BitmapR32F =Bitmap; + + using BitmapRG8 =Bitmap; + using BitmapRG16 =Bitmap; + using BitmapRG32U =Bitmap; + using BitmapRG32F =Bitmap; + + using BitmapRGBA8 =Bitmap; + using BitmapRGBA16 =Bitmap; + using BitmapRGBA32U =Bitmap; + using BitmapRGBA32F =Bitmap; }//namespace hgl #endif//HGL_2D_BITMAP_INCLUDE From e05494c0ff789c8840f8ce188d04ce2e4d546e4b Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 15:37:32 +0800 Subject: [PATCH 02/16] added PutPixel/GetPixel in Bitmap<> --- inc/hgl/2d/Bitmap.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index 2e2fdd2..0dae33b 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -159,6 +159,40 @@ namespace hgl delete[] temp; } + + void PutPixel(int x,int y,const T *color) + { + if(!data||!color)return; + + if(x<0||y<0||x>=width||y>=height)return; + + T *p=data+(y*width+x)*CHANNELS; + + for(uint i=0;i=width||y>=height)return(false); + + T *p=data+(y*width+x)*CHANNELS; + + for(uint i=0;i class Bitmap using BitmapR8 =Bitmap; From 82cdaa44c96120a53a838cf63ceb1b93bb8bf641 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 16:04:44 +0800 Subject: [PATCH 03/16] added GetWidth/GetHeight .... functions at Bitmap<> --- inc/hgl/2d/Bitmap.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index 0dae33b..39a6989 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -27,6 +27,14 @@ namespace hgl delete[] data; } + const uint GetWidth()const{return width;} + const uint GetHeight()const{return height;} + const uint GetTotalPixels()const{return width*height;} + const uint GetLineBytea()const{return width*CHANNELS*sizeof(T);} + const uint GetTotalBytes()const{return width*height*CHANNELS*sizeof(T);} + + T *GetData(){return data;} + bool Create(uint w,uint h) { if(!w||!h)return(false); From 20cae9a4628c9f446da319a571bd3490f23571b7 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 18:16:11 +0800 Subject: [PATCH 04/16] removed CHANNELS in Bitmap<> --- inc/hgl/2d/Bitmap.h | 166 ++++++++------------------------------------ 1 file changed, 28 insertions(+), 138 deletions(-) diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index 39a6989..d296417 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -3,14 +3,21 @@ #include #include +#include namespace hgl { + template + static void FillPixels(T *p,const T &color,const int length) + { + std::fill_n(p,length,color); + } + /** * 简单的2D象素处理 */ - template class Bitmap + template class Bitmap { - uint width,height; + int width,height; T *data; @@ -27,13 +34,17 @@ namespace hgl delete[] data; } - const uint GetWidth()const{return width;} - const uint GetHeight()const{return height;} - const uint GetTotalPixels()const{return width*height;} - const uint GetLineBytea()const{return width*CHANNELS*sizeof(T);} - const uint GetTotalBytes()const{return width*height*CHANNELS*sizeof(T);} + 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 *GetData(){return data;} + T *GetData(int x,int y) + { + return (x<0||x>=width||y<0||y>=height)?nullptr:data+(y*width+x); + } bool Create(uint w,uint h) { @@ -49,7 +60,7 @@ namespace hgl delete[] data; - data=new T[width*height*CHANNELS]; + data=new T[width*height]; return(true); } @@ -65,95 +76,23 @@ namespace hgl width=height=0; } - void ClearColor(T *color) + void ClearColor(const T &color) { - if(!data||!color)return; + if(!data)return; - uint total=width*height; - - T *p=data; - - for(size_t i=0; i *outputs) - { - if(!data||!outputs) - return(false); - - T *sp=data; - AutoDeleteArray op=new T *[CHANNELS]; - - for(uint i=0;i *inputs) - { - if(!data||!inputs) - return(false); - - T *dp=data; - AutoDeleteArray ip=new T *[CHANNELS]; - - for(uint i=0;i(data,color,width*height); } void Flip() { if(!data||height<=1)return; - const uint line_pixels=width*CHANNELS; - const uint line_bytes=width*CHANNELS*sizeof(T); + const uint line_bytes=width*sizeof(T); - T *temp=new T[line_pixels]; + T *temp=new T[width]; T *top=data; - T *bottom=data+(line_pixels*(height-1)); + T *bottom=data+(width*(height-1)); while(top=width||y>=height)return; - - T *p=data+(y*width+x)*CHANNELS; - - for(uint i=0;i=width||y>=height)return(false); - - T *p=data+(y*width+x)*CHANNELS; - - for(uint i=0;i class Bitmap - - using BitmapR8 =Bitmap; - using BitmapR16 =Bitmap; - using BitmapR32U =Bitmap; - using BitmapR32F =Bitmap; - - using BitmapRG8 =Bitmap; - using BitmapRG16 =Bitmap; - using BitmapRG32U =Bitmap; - using BitmapRG32F =Bitmap; - - using BitmapRGBA8 =Bitmap; - using BitmapRGBA16 =Bitmap; - using BitmapRGBA32U =Bitmap; - using BitmapRGBA32F =Bitmap; + };//template class Bitmap }//namespace hgl #endif//HGL_2D_BITMAP_INCLUDE From ca74184d390f50dba5a24c6c016930f0b28f76ae Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 18:16:23 +0800 Subject: [PATCH 05/16] added DrawGeometry.h --- inc/hgl/2d/DrawGeometry.h | 409 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 inc/hgl/2d/DrawGeometry.h diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h new file mode 100644 index 0000000..17b33e3 --- /dev/null +++ b/inc/hgl/2d/DrawGeometry.h @@ -0,0 +1,409 @@ +#pragma once + +#include +#include + +namespace hgl +{ + template class DrawGeometry + { + public: + + using FormatBitmap=Bitmap; + + protected: + + FormatBitmap *bitmap; + + T draw_color; + + public: + + DrawGeometry(FormatBitmap *fb) + { + bitmap=fb; + } + + virtual ~DrawGeometry()=default; + + virtual void SetDrawColor(const T &color) + { + draw_color=color; + } + + 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=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) + { + 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++; + } + + 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++) + { + int dy=cy-y; + int dy2=dy*dy; + + for(int cx=x0;cx<=x1;cx++) + { + int dx=cx-x; + int dx2=dx*dx; + + 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=x1;x1=y2;y2=x;y=y1;y1=x2;x2=y; + + 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++); + } + } + } + } + + 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 +}//namespace hgl From 713a9f98b3f183ef148d68e8ded4867d9c9d3cce Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 18:48:55 +0800 Subject: [PATCH 06/16] added Blend.h and supported it. --- inc/hgl/2d/Bitmap.h | 167 ++++----- inc/hgl/2d/Blend.h | 57 +++ inc/hgl/2d/DrawGeometry.h | 737 ++++++++++++++++++++------------------ 3 files changed, 530 insertions(+), 431 deletions(-) create mode 100644 inc/hgl/2d/Blend.h 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 From c41cd9283d8c66c7c6aa3ee0ae6e06ccdc824061 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 19:36:48 +0800 Subject: [PATCH 07/16] used single Blend class in Bitmap<> --- inc/hgl/2d/Blend.h | 41 +++------------------------------------ inc/hgl/2d/DrawGeometry.h | 19 ++++++++---------- 2 files changed, 11 insertions(+), 49 deletions(-) diff --git a/inc/hgl/2d/Blend.h b/inc/hgl/2d/Blend.h index eb6b5fe..3b16ad0 100644 --- a/inc/hgl/2d/Blend.h +++ b/inc/hgl/2d/Blend.h @@ -6,52 +6,17 @@ 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) + virtual const T operator()(const T &src,const T &)const { return src; } - virtual const T &BlendAlpha(const T &src,const T &dst,const float alpha) + virtual const T operator()(const T &src,const T &,const float &)const { - 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 + };//template struct 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 84aa1cd..0487d22 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -21,6 +21,7 @@ namespace hgl T draw_color; float alpha; + BlendColor no_blend; BlendColor *blend; public: @@ -28,8 +29,9 @@ namespace hgl DrawGeometry(FormatBitmap *fb) { bitmap=fb; - draw_color=0; + hgl_zero(draw_color); alpha=1; + blend=&no_blend; } virtual ~DrawGeometry()=default; @@ -44,14 +46,9 @@ namespace hgl blend=bc; } - virtual void SetBlend(const BlendMode &mode) - { - blend->mode=mode; - } - void CloseBlend() { - blend->mode=BlendMode.NoBlend; + blend=&no_blend; } void SetAlpha(const float &a) @@ -80,7 +77,7 @@ namespace hgl if(!p)return(false); - *p=blend->Blend(draw_color,*p,alpha); + *p=(*blend)(draw_color,*p,alpha); return(true); } @@ -102,7 +99,7 @@ namespace hgl T *p=bitmap->GetData(x,y); for(int i=0;iBlend(draw_color,*p,alpha); + *p++=(*blend)(draw_color,*p,alpha); return(true); } @@ -129,7 +126,7 @@ namespace hgl for(int y=t;yBlend(draw_color,*p,alpha); + *p++=(*blend)Blend(draw_color,*p,alpha); p+=width-w; } @@ -156,7 +153,7 @@ namespace hgl for(int i=0;iBlend(draw_color,*p,alpha); + *p=(*blend)Blend(draw_color,*p,alpha); p+=line_bytes; } From d7f93c75260e10bd0ecf5caa1e0c984b73828523 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 19:51:24 +0800 Subject: [PATCH 08/16] added DrawMonoBitmap in Bitmap<> --- inc/hgl/2d/DrawGeometry.h | 42 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h index 0487d22..9c70cfc 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -126,7 +126,7 @@ namespace hgl for(int y=t;y=bitmap->GetWidth()-w)return; + if(top<0||top>=bitmap->GetHeight()-h)return; + + const uint8 *sp=data; + uint8 bit; + T *tp=bitmap->GetData(left,top); + + const uint line_wrap=bitmap->GetWidth()-w; + + bit=1<<7; + + for(int row=0;row>=1; + if(bit==0) + { + ++sp; + bit=1<<7; + } + } + + tp+=line_wrap; + } + } };//template class DrawGeometry }//namespace bitmap }//namespace hgl From c19d0fffe725eddd04e623d53c36b0400c16aa4a Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 20:19:51 +0800 Subject: [PATCH 09/16] added BlendBitmap<> --- inc/hgl/2d/Bitmap.h | 6 ++++++ inc/hgl/2d/Blend.h | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index fa30195..bbc6812 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -48,6 +48,12 @@ namespace hgl return (x<0||x>=width||y<0||y>=height)?nullptr:data+(y*width+x); } + const T *GetData()const{return data;} + const T *GetData(int x,int y)const + { + return (x<0||x>=width||y<0||y>=height)?nullptr:data+(y*width+x); + } + bool Create(uint w,uint h) { if(!w||!h)return(false); diff --git a/inc/hgl/2d/Blend.h b/inc/hgl/2d/Blend.h index 3b16ad0..618ec91 100644 --- a/inc/hgl/2d/Blend.h +++ b/inc/hgl/2d/Blend.h @@ -1,6 +1,7 @@ -#pragma once +#pragma once #include +#include namespace hgl { @@ -18,5 +19,15 @@ namespace hgl return src; } };//template struct BlendColor + + /** + * 位图混合处理模板 + */ + template class BlendBitmap + { + public: + + void operator ()(const Bitmap *src,Bitmap
*dst,const float alpha)const; + };//template class BlendBitmap }//namespace bitmap -}//namespace hgl \ No newline at end of file +}//namespace hgl From 0fd9552b4ed7daf64d06437e5b7e643c29bcf8a9 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Tue, 11 Jul 2023 21:42:23 +0800 Subject: [PATCH 10/16] fixed a bug --- inc/hgl/2d/DrawGeometry.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h index 9c70cfc..d92e70f 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -148,13 +148,12 @@ namespace hgl if(length<=0)return(false); - const uint line_bytes=bitmap->GetLineBytes(); T *p=bitmap->GetData(x,y); for(int i=0;i Date: Wed, 26 Jul 2023 22:29:49 +0800 Subject: [PATCH 11/16] added BitmapFont.h --- inc/hgl/2d/BitmapFont.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 inc/hgl/2d/BitmapFont.h diff --git a/inc/hgl/2d/BitmapFont.h b/inc/hgl/2d/BitmapFont.h new file mode 100644 index 0000000..42920a7 --- /dev/null +++ b/inc/hgl/2d/BitmapFont.h @@ -0,0 +1,18 @@ +#pragma once +#include + +namespace hgl +{ + /* + * 基于位图的字体 + */ + class BitmapFont + { + uint bits; + uint width,height; + + public: + + + };//class BitmapFont +}//namespace hgl From 1c2223310197efabf5901c7e0dc00f7c3aafe2e4 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Wed, 26 Jul 2023 22:30:10 +0800 Subject: [PATCH 12/16] used AutoDeleteArray<> instead of calloc/free --- inc/hgl/2d/DrawGeometry.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h index d92e70f..9ed3b9a 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -347,7 +347,7 @@ namespace hgl void DrawSector(int x0, int y0, uint r, uint stangle, uint endangle) { int i, j; - int *xy; + AutoDeleteArray xy(20); int bx, ex, bxd, exd, bxf, exf, ben; int tn, x, y; int xmax; @@ -356,7 +356,6 @@ namespace hgl 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; @@ -437,7 +436,6 @@ namespace hgl xy[12]++; xy[15]++; } - free(xy); } void DrawMonoBitmap(const int left,const int top,const uint8 *data,const int w,const int h) From 24ab6f5f9f5334f9ff5cdce48b81fb5625a182c3 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Fri, 15 Sep 2023 18:19:51 +0800 Subject: [PATCH 13/16] Improved Bitmap<>,BlendBitmap<>,DrawGeometry<> --- inc/hgl/2d/Bitmap.h | 15 +++++++- inc/hgl/2d/Blend.h | 75 ++++++++++++++++++++++++++++++++++++++- inc/hgl/2d/DrawGeometry.h | 11 +++--- 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/inc/hgl/2d/Bitmap.h b/inc/hgl/2d/Bitmap.h index bbc6812..d54232e 100644 --- a/inc/hgl/2d/Bitmap.h +++ b/inc/hgl/2d/Bitmap.h @@ -2,6 +2,7 @@ #define HGL_2D_BITMAP_INCLUDE #include +#include #include #include namespace hgl @@ -17,7 +18,7 @@ namespace hgl /** * 简单的2D象素处理 */ - template class Bitmap + template class Bitmap { int width,height; @@ -36,6 +37,9 @@ namespace hgl delete[] data; } + const uint GetChannels ()const{return C;} + const uint GetChannelBits ()const{return (sizeof(T)/C)<<3;} + const int GetWidth ()const{return width;} const int GetHeight ()const{return height;} const uint GetTotalPixels ()const{return width*height;} @@ -115,6 +119,15 @@ namespace hgl delete[] temp; } };//template class Bitmap + + using BitmapGrey8=Bitmap; + using BitmapRG8=Bitmap; + using BitmapRGB8=Bitmap; + using BitmapRGBA8=Bitmap; + + using BitmapU16=Bitmap; + using BitmapU32=Bitmap; }//namespace bitmap }//namespace hgl #endif//HGL_2D_BITMAP_INCLUDE + diff --git a/inc/hgl/2d/Blend.h b/inc/hgl/2d/Blend.h index 618ec91..f805e89 100644 --- a/inc/hgl/2d/Blend.h +++ b/inc/hgl/2d/Blend.h @@ -27,7 +27,80 @@ namespace hgl { public: - void operator ()(const Bitmap *src,Bitmap
*dst,const float alpha)const; + void operator ()(const ST *src,DT *dst,const float alpha)const; };//template class BlendBitmap + + struct BlendColorU32Additive:public bitmap::BlendColor + { + const uint32 operator()(const uint32 &src,const uint32 &dst)const + { + uint64 result=src+dst; + + return (result>HGL_U32_MAX)?HGL_U32_MAX:(result&HGL_U32_MAX); + } + + const uint32 operator()(const uint32 &src,const uint32 &dst,const float &alpha)const + { + uint64 result=src*alpha+dst; + + return (result>HGL_U32_MAX)?HGL_U32_MAX:(result&HGL_U32_MAX); + } + }; + + struct BlendColorRGBA8:public bitmap::BlendColor + { + const Vector4u8 operator()(const Vector4u8 &src,const Vector4u8 &dst)const + { + uint8 na=255-src.a; + + return Vector4u8((src.r*src.a+dst.r*na)/255, + (src.g*src.a+dst.g*na)/255, + (src.b*src.a+dst.b*na)/255, + dst.a); + } + + const Vector4u8 operator()(const Vector4u8 &src,const Vector4u8 &dst,const float &alpha)const + { + uint8 a=src.a*alpha; + uint8 na=255-src.a; + + return Vector4u8((src.r*src.a+dst.r*na)/255, + (src.g*src.a+dst.g*na)/255, + (src.b*src.a+dst.b*na)/255, + dst.a); + } + }; + + template<> void bitmap::BlendBitmap::operator()(const BitmapRGBA8 *src_bitmap,BitmapRGB8 *dst_bitmap,const float alpha)const + { + if(!src_bitmap||!dst_bitmap||alpha<=0)return; + + const uint width=src_bitmap->GetWidth(); + const uint height=src_bitmap->GetHeight(); + + if(width!=dst_bitmap->GetWidth()||height!=dst_bitmap->GetHeight()) + return; + + Vector3u8 *dst=dst_bitmap->GetData(); + const Vector4u8 *src=src_bitmap->GetData(); + + float a; + float na; + + for(uint i=0;ia*alpha; + na=255-src->a; + + dst->r=(src->r*a+dst->r*na)/255; + dst->g=(src->g*a+dst->g*na)/255; + dst->b=(src->b*a+dst->b*na)/255; + + ++dst; + ++src; + } + } + + using BlendBitmapRGBA8toRGB8=bitmap::BlendBitmap; }//namespace bitmap }//namespace hgl diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h index 9ed3b9a..171e0e0 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -1,19 +1,15 @@ #pragma once #include -#include +#include #include namespace hgl { namespace bitmap { - template class DrawGeometry + template class DrawGeometry { - public: - - using FormatBitmap=Bitmap; - protected: FormatBitmap *bitmap; @@ -476,5 +472,8 @@ namespace hgl } } };//template class DrawGeometry + + using DrawGeometryU32=DrawGeometry; + using DrawGeometryRGBA8=DrawGeometry; }//namespace bitmap }//namespace hgl From 04f182e78cd1508f3c0480777ad8f15bc0f87752 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Fri, 15 Sep 2023 18:20:06 +0800 Subject: [PATCH 14/16] added TGA.h/tga.cpp --- inc/hgl/2d/TGA.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++ src/Bitmap/tga.cpp | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 inc/hgl/2d/TGA.h create mode 100644 src/Bitmap/tga.cpp diff --git a/inc/hgl/2d/TGA.h b/inc/hgl/2d/TGA.h new file mode 100644 index 0000000..3a44b88 --- /dev/null +++ b/inc/hgl/2d/TGA.h @@ -0,0 +1,51 @@ +#pragma once + +#include +namespace hgl +{ + namespace imgfmt + { + constexpr const uint TGA_IMAGE_TYPE_COLOR_MAP =1; + constexpr const uint TGA_IMAGE_TYPE_TRUE_COLOR =2; + constexpr const uint TGA_IMAGE_TYPE_GRAYSCALE =3; + + constexpr const uint TGA_DIRECTION_LOWER_LEFT =0; + constexpr const uint TGA_DIRECTION_UPPER_LEFT =1; + +#pragma pack(push,1) + struct TGAHeader + { + uint8 id; + uint8 color_map_type; + uint8 image_type; // 1 colormap image ,2 true-color,3 grayscale + + uint16 color_map_first; + uint16 color_map_length; + uint8 color_map_size; + + uint16 x_origin; + uint16 y_origin; + + uint16 width; + uint16 height; + uint8 bit; + uint8 image_desc; + }; + + union TGAImageDesc + { + uint8 image_desc; + struct + { + uint alpha_depth:4; + uint reserved:1; + uint direction:1; //0 lower-left,1 upper left + }; + }; +#pragma pack(pop) + + constexpr size_t TGAHeaderSize=sizeof(TGAHeader); + + bool FillTGAHeader(TGAHeader *header,const uint16 width,const uint16 height,const uint8 channels,const uint8 single_channel_bits=8); + }//namespace imgfmt +}//namespace hgl diff --git a/src/Bitmap/tga.cpp b/src/Bitmap/tga.cpp new file mode 100644 index 0000000..67c8c9c --- /dev/null +++ b/src/Bitmap/tga.cpp @@ -0,0 +1,45 @@ +#include + +namespace hgl +{ + namespace imgfmt + { + bool FillTGAHeader(TGAHeader *header,const uint16 width,const uint16 height,const uint8 channels,const uint8 single_channel_bits) + { + if(!header)return(false); + if(!width||!height)return(false); + + if(channels!=1 + &&channels!=3 + &&channels!=4)return(false); + + memset(header,0,sizeof(TGAHeader)); + + header->width=width; + header->height=height; + + TGAImageDesc desc; + + desc.image_desc=0; + + if(channels==1) + { + header->image_type=3; + header->bit=single_channel_bits; + } + else + { + header->image_type=2; + header->bit=channels*single_channel_bits; + + if(channels==4) + desc.alpha_depth=single_channel_bits; + } + + desc.direction=TGA_DIRECTION_UPPER_LEFT; + + header->image_desc=desc.image_desc; + return(true); + } + }//namespace imgfmt +}//namespace hgl \ No newline at end of file From a5d8d578e73026a86cf8448db2b29f5cd9f80de9 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Fri, 15 Sep 2023 18:20:46 +0800 Subject: [PATCH 15/16] added Bitmap I/O in TGAFormat --- inc/hgl/2d/BitmapFont.h | 18 ------- inc/hgl/2d/BitmapLoad.h | 90 ++++++++++++++++++++++++++++++++++ inc/hgl/2d/BitmapSave.h | 33 +++++++++++++ src/Bitmap/BitmapTGAStream.cpp | 70 ++++++++++++++++++++++++++ 4 files changed, 193 insertions(+), 18 deletions(-) delete mode 100644 inc/hgl/2d/BitmapFont.h create mode 100644 inc/hgl/2d/BitmapLoad.h create mode 100644 inc/hgl/2d/BitmapSave.h create mode 100644 src/Bitmap/BitmapTGAStream.cpp diff --git a/inc/hgl/2d/BitmapFont.h b/inc/hgl/2d/BitmapFont.h deleted file mode 100644 index 42920a7..0000000 --- a/inc/hgl/2d/BitmapFont.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include - -namespace hgl -{ - /* - * 基于位图的字体 - */ - class BitmapFont - { - uint bits; - uint width,height; - - public: - - - };//class BitmapFont -}//namespace hgl diff --git a/inc/hgl/2d/BitmapLoad.h b/inc/hgl/2d/BitmapLoad.h new file mode 100644 index 0000000..dc8eb31 --- /dev/null +++ b/inc/hgl/2d/BitmapLoad.h @@ -0,0 +1,90 @@ +#pragma once +#include +#include + +namespace hgl +{ + namespace bitmap + { + struct BitmapLoader + { + virtual const uint OnChannels()const=0; + virtual const uint OnChannelBits()const=0; + + const uint OnPixelBits()const + { + return OnChannelBits()*OnChannels(); + } + + virtual void *OnRecvBitmap(uint w,uint h)=0; + + virtual void OnLoadFailed()=0; + virtual void OnFlip()=0; + }; + + template struct BitmapLoaderImpl:public BitmapLoader + { + T *bmp; + + public: + + BitmapLoaderImpl() + { + bmp=nullptr; + } + + const uint OnChannels()const override{return bmp->GetChannels();} + const uint OnChannelBits()const override{return bmp->GetChannelBits();} + + void *OnRecvBitmap(uint w,uint h) override + { + if(!bmp) + bmp=new T; + + bmp->Create(w,h); + return bmp->GetData(); + } + + void OnLoadFailed() override + { + SAFE_CLEAR(bmp); + } + + void OnFlip() override + { + if(bmp) + bmp->Flip(); + } + }; + + bool LoadBitmapFromTGAStream(io::InputStream *,BitmapLoader *); + + template + inline T *LoadBitmapFromTGA(io::InputStream *is) + { + BitmapLoaderImpl bli; + + if(LoadBitmapFromTGAStream(is,&bli)) + return bli.bmp; + + return(nullptr); + } + + inline BitmapRGB8 *LoadBitmapRGB8FromTGA(io::InputStream *is){return LoadBitmapFromTGA(is);} + inline BitmapRGBA8 *LoadBitmapRGBA8FromTGA(io::InputStream *is){return LoadBitmapFromTGA(is);} + + template + inline T *LoadBitmapFromTGA(const OSString &filename) + { + io::OpenFileInputStream fis(filename); + + if(!fis) + return(false); + + return LoadBitmapFromTGA(&fis); + } + + inline BitmapRGB8 *LoadBitmapRGB8FromTGA(const OSString &filename){return LoadBitmapFromTGA(filename);} + inline BitmapRGBA8 *LoadBitmapRGBA8FromTGA(const OSString &filename){return LoadBitmapFromTGA(filename);} + }//namespace bitmap +}//namespace hgl \ No newline at end of file diff --git a/inc/hgl/2d/BitmapSave.h b/inc/hgl/2d/BitmapSave.h new file mode 100644 index 0000000..433e46e --- /dev/null +++ b/inc/hgl/2d/BitmapSave.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include + +namespace hgl +{ + namespace bitmap + { + bool SaveBitmapToTGA(io::OutputStream *os,void *data,uint width,uint height,uint channels,uint single_channel_bits); + + template + inline bool SaveBitmapToTGA(io::OutputStream *os,const T *bmp) + { + if(!os||!bmp)return(false); + + return SaveBitmapToTGA(os,(void *)(bmp->GetData()),bmp->GetWidth(),bmp->GetHeight(),bmp->GetChannels(),bmp->GetChannelBits()); + } + + template + inline bool SaveBitmapToTGA(const OSString &filename,T *bmp) + { + if(filename.IsEmpty()||!bmp) + return(false); + + io::OpenFileOutputStream fos(filename,io::FileOpenMode::CreateTrunc); + + if(!fos) + return(false); + + return SaveBitmapToTGA(fos,bmp); + } + }//namespace bitmap +}//namespace hgl \ No newline at end of file diff --git a/src/Bitmap/BitmapTGAStream.cpp b/src/Bitmap/BitmapTGAStream.cpp new file mode 100644 index 0000000..ecdff8c --- /dev/null +++ b/src/Bitmap/BitmapTGAStream.cpp @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +namespace hgl +{ + using namespace io; + using namespace imgfmt; + + namespace bitmap + { + bool LoadBitmapFromTGAStream(io::InputStream *is,BitmapLoader *bl) + { + if(!is||!bl)return(false); + + TGAHeader tga_header; + TGAImageDesc tga_desc; + + if(is->Read(&tga_header,TGAHeaderSize)!=TGAHeaderSize) + return(false); + + if(tga_header.image_type!=TGA_IMAGE_TYPE_TRUE_COLOR) + return(false); + + if(tga_header.bit!=bl->OnPixelBits()) + return(false); + + tga_desc.image_desc=tga_header.image_desc; + + void *bmp=bl->OnRecvBitmap(tga_header.width,tga_header.height); + + const uint total_bytes=(tga_header.width*tga_header.height*tga_header.bit)>>3; + + if(is->Read(bmp,total_bytes)!=total_bytes) + { + bl->OnLoadFailed(); + return(false); + } + + if(tga_desc.direction==TGA_DIRECTION_LOWER_LEFT) + bl->OnFlip(); + + return(true); + } + + /** + * TGAʽBitmapݵ + */ + bool SaveBitmapToTGA(io::OutputStream *os,void *data,uint width,uint height,uint channels,uint single_channel_bits) + { + if(!os||!data||width<=0||height<=0||channels<=0||single_channel_bits<=0) + return(false); + + TGAHeader tga_header; + + const uint total_bytes=(width*height*channels*single_channel_bits)>>3; + + FillTGAHeader(&tga_header,width,height,channels,single_channel_bits); + + if(os->Write(&tga_header,TGAHeaderSize)!=TGAHeaderSize) + return(false); + + if(os->Write(data,total_bytes)!=total_bytes) + return(false); + + return(true); + } + }//namespace bitmap +}//namespace hgl From 004bfa7e735c718d9214db3f635d148994b8cb55 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Fri, 15 Sep 2023 20:15:56 +0800 Subject: [PATCH 16/16] added DrawGeometryRGB8 define. --- inc/hgl/2d/DrawGeometry.h | 1 + 1 file changed, 1 insertion(+) diff --git a/inc/hgl/2d/DrawGeometry.h b/inc/hgl/2d/DrawGeometry.h index 171e0e0..9899593 100644 --- a/inc/hgl/2d/DrawGeometry.h +++ b/inc/hgl/2d/DrawGeometry.h @@ -474,6 +474,7 @@ namespace hgl };//template class DrawGeometry using DrawGeometryU32=DrawGeometry; + using DrawGeometryRGB8=DrawGeometry; using DrawGeometryRGBA8=DrawGeometry; }//namespace bitmap }//namespace hgl