Merge remote-tracking branch 'hyzgame/master'
This commit is contained in:
commit
fd7e7e3788
@ -1,13 +1,133 @@
|
|||||||
#ifndef HGL_2D_BITMAP_INCLUDE
|
#ifndef HGL_2D_BITMAP_INCLUDE
|
||||||
#define HGL_2D_BITMAP_INCLUDE
|
#define HGL_2D_BITMAP_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/type/DataType.h>
|
||||||
|
#include<hgl/type/String.h>
|
||||||
|
#include<hgl/math/HalfFloat.h>
|
||||||
|
#include<iterator>
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
|
namespace bitmap
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
static void FillPixels(T *p,const T &color,const int length)
|
||||||
|
{
|
||||||
|
std::fill_n(p,length,color);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 简单的2D象素处理
|
* 简单的2D象素处理
|
||||||
*/
|
*/
|
||||||
template<typename T> class Bitmap2D
|
template<typename T,uint C> class Bitmap
|
||||||
{
|
{
|
||||||
};//
|
int width,height;
|
||||||
|
|
||||||
|
T *data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Bitmap()
|
||||||
|
{
|
||||||
|
data=nullptr;
|
||||||
|
width=height=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Bitmap()
|
||||||
|
{
|
||||||
|
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;}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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<T>(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<bottom)
|
||||||
|
{
|
||||||
|
memcpy(temp,top,line_bytes);
|
||||||
|
memcpy(top,bottom,line_bytes);
|
||||||
|
memcpy(bottom,temp,line_bytes);
|
||||||
|
|
||||||
|
top+=width;
|
||||||
|
bottom-=width;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] temp;
|
||||||
|
}
|
||||||
|
};//template<typename T> class Bitmap
|
||||||
|
|
||||||
|
using BitmapGrey8=Bitmap<uint8,1>;
|
||||||
|
using BitmapRG8=Bitmap<Vector2u8,2>;
|
||||||
|
using BitmapRGB8=Bitmap<Vector3u8,3>;
|
||||||
|
using BitmapRGBA8=Bitmap<Vector4u8,4>;
|
||||||
|
|
||||||
|
using BitmapU16=Bitmap<uint16,1>;
|
||||||
|
using BitmapU32=Bitmap<uint32,1>;
|
||||||
|
}//namespace bitmap
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
#endif//HGL_2D_BITMAP_INCLUDE
|
#endif//HGL_2D_BITMAP_INCLUDE
|
||||||
|
|
||||||
|
90
inc/hgl/2d/BitmapLoad.h
Normal file
90
inc/hgl/2d/BitmapLoad.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#pragma once
|
||||||
|
#include<hgl/2d/Bitmap.h>
|
||||||
|
#include<hgl/io/FileInputStream.h>
|
||||||
|
|
||||||
|
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<typename T> 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<typename T>
|
||||||
|
inline T *LoadBitmapFromTGA(io::InputStream *is)
|
||||||
|
{
|
||||||
|
BitmapLoaderImpl<T> bli;
|
||||||
|
|
||||||
|
if(LoadBitmapFromTGAStream(is,&bli))
|
||||||
|
return bli.bmp;
|
||||||
|
|
||||||
|
return(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BitmapRGB8 *LoadBitmapRGB8FromTGA(io::InputStream *is){return LoadBitmapFromTGA<BitmapRGB8>(is);}
|
||||||
|
inline BitmapRGBA8 *LoadBitmapRGBA8FromTGA(io::InputStream *is){return LoadBitmapFromTGA<BitmapRGBA8>(is);}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T *LoadBitmapFromTGA(const OSString &filename)
|
||||||
|
{
|
||||||
|
io::OpenFileInputStream fis(filename);
|
||||||
|
|
||||||
|
if(!fis)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
return LoadBitmapFromTGA<T>(&fis);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BitmapRGB8 *LoadBitmapRGB8FromTGA(const OSString &filename){return LoadBitmapFromTGA<BitmapRGB8>(filename);}
|
||||||
|
inline BitmapRGBA8 *LoadBitmapRGBA8FromTGA(const OSString &filename){return LoadBitmapFromTGA<BitmapRGBA8>(filename);}
|
||||||
|
}//namespace bitmap
|
||||||
|
}//namespace hgl
|
33
inc/hgl/2d/BitmapSave.h
Normal file
33
inc/hgl/2d/BitmapSave.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#include<hgl/2d/Bitmap.h>
|
||||||
|
#include<hgl/io/FileOutputStream.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace bitmap
|
||||||
|
{
|
||||||
|
bool SaveBitmapToTGA(io::OutputStream *os,void *data,uint width,uint height,uint channels,uint single_channel_bits);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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<typename T>
|
||||||
|
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
|
106
inc/hgl/2d/Blend.h
Normal file
106
inc/hgl/2d/Blend.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<hgl/type/DataType.h>
|
||||||
|
#include<hgl/2d/Bitmap.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace bitmap
|
||||||
|
{
|
||||||
|
template<typename T> struct BlendColor
|
||||||
|
{
|
||||||
|
virtual const T operator()(const T &src,const T &)const
|
||||||
|
{
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const T operator()(const T &src,const T &,const float &)const
|
||||||
|
{
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
};//template<typename T> struct BlendColor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 位图混合处理模板
|
||||||
|
*/
|
||||||
|
template<typename ST,typename DT> class BlendBitmap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void operator ()(const ST *src,DT *dst,const float alpha)const;
|
||||||
|
};//template<typename ST,typename DT> class BlendBitmap
|
||||||
|
|
||||||
|
struct BlendColorU32Additive:public bitmap::BlendColor<uint32>
|
||||||
|
{
|
||||||
|
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<Vector4u8>
|
||||||
|
{
|
||||||
|
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<BitmapRGBA8,BitmapRGB8>::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;i<width*height;i++)
|
||||||
|
{
|
||||||
|
a=src->a*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<BitmapRGBA8,BitmapRGB8>;
|
||||||
|
}//namespace bitmap
|
||||||
|
}//namespace hgl
|
480
inc/hgl/2d/DrawGeometry.h
Normal file
480
inc/hgl/2d/DrawGeometry.h
Normal file
@ -0,0 +1,480 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<hgl/2d/Bitmap.h>
|
||||||
|
#include<hgl/2d/Blend.h>
|
||||||
|
#include<hgl/math/FastTriangle.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
namespace bitmap
|
||||||
|
{
|
||||||
|
template<typename T,typename FormatBitmap> class DrawGeometry
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
FormatBitmap *bitmap;
|
||||||
|
|
||||||
|
T draw_color;
|
||||||
|
float alpha;
|
||||||
|
|
||||||
|
BlendColor<T> no_blend;
|
||||||
|
BlendColor<T> *blend;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DrawGeometry(FormatBitmap *fb)
|
||||||
|
{
|
||||||
|
bitmap=fb;
|
||||||
|
hgl_zero(draw_color);
|
||||||
|
alpha=1;
|
||||||
|
blend=&no_blend;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~DrawGeometry()=default;
|
||||||
|
|
||||||
|
virtual void SetDrawColor(const T &color)
|
||||||
|
{
|
||||||
|
draw_color=color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBlend(BlendColor<T> *bc)
|
||||||
|
{
|
||||||
|
blend=bc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseBlend()
|
||||||
|
{
|
||||||
|
blend=&no_blend;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)(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;i<length;i++)
|
||||||
|
*p++=(*blend)(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;y<t+h;y++)
|
||||||
|
{
|
||||||
|
for(int i=0;i<length;i++)
|
||||||
|
*p++=(*blend)(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);
|
||||||
|
|
||||||
|
T *p=bitmap->GetData(x,y);
|
||||||
|
|
||||||
|
for(int i=0;i<length;i++)
|
||||||
|
{
|
||||||
|
*p=(*blend)(draw_color,*p,alpha);
|
||||||
|
p+=width;
|
||||||
|
}
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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((y2<y1&&x2<x1)||(y1<=y2&&x1>x2))
|
||||||
|
{
|
||||||
|
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((y2<y1&&x2<x1)||(y1<=y2&&x1>x2))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
AutoDeleteArray<int> xy(20);
|
||||||
|
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[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(stangle<endangle)
|
||||||
|
{
|
||||||
|
j=(bx+1)*2;
|
||||||
|
for(i=0;i<ben;i++)
|
||||||
|
{
|
||||||
|
PutPixel(xy[j], xy[j+1]);
|
||||||
|
j+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(stangle>endangle)
|
||||||
|
{
|
||||||
|
j=(bx+1)*2;
|
||||||
|
for(i=bx+1;i<8;i++)
|
||||||
|
{
|
||||||
|
PutPixel(xy[j], xy[j+1]);
|
||||||
|
j+=2;
|
||||||
|
}
|
||||||
|
j=0;
|
||||||
|
for(i=0;i<ex;i++)
|
||||||
|
{
|
||||||
|
PutPixel(xy[j], xy[j+1]);
|
||||||
|
j+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i=bx*2;
|
||||||
|
if((x>bxd)^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]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawMonoBitmap(const int left,const int top,const uint8 *data,const int w,const int h)
|
||||||
|
{
|
||||||
|
if(!data)return;
|
||||||
|
|
||||||
|
if(left<0||left>=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<h;row++)
|
||||||
|
{
|
||||||
|
for(int col=0;col<w;col++)
|
||||||
|
{
|
||||||
|
if(*sp&bit)
|
||||||
|
{
|
||||||
|
*tp=(*blend)(draw_color,*tp,alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
++tp;
|
||||||
|
|
||||||
|
bit>>=1;
|
||||||
|
if(bit==0)
|
||||||
|
{
|
||||||
|
++sp;
|
||||||
|
bit=1<<7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tp+=line_wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};//template<typename T,uint CHANNELS> class DrawGeometry
|
||||||
|
|
||||||
|
using DrawGeometryU32=DrawGeometry<uint32,BitmapU32>;
|
||||||
|
using DrawGeometryRGB8=DrawGeometry<Vector3u8,BitmapRGB8>;
|
||||||
|
using DrawGeometryRGBA8=DrawGeometry<Vector4u8,BitmapRGBA8>;
|
||||||
|
}//namespace bitmap
|
||||||
|
}//namespace hgl
|
51
inc/hgl/2d/TGA.h
Normal file
51
inc/hgl/2d/TGA.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<hgl/platform/Platform.h>
|
||||||
|
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
|
70
src/Bitmap/BitmapTGAStream.cpp
Normal file
70
src/Bitmap/BitmapTGAStream.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include<hgl/2d/BitmapLoad.h>
|
||||||
|
#include<hgl/2d/TGA.h>
|
||||||
|
#include<hgl/io/InputStream.h>
|
||||||
|
#include<hgl/io/OutputStream.h>
|
||||||
|
|
||||||
|
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
|
45
src/Bitmap/tga.cpp
Normal file
45
src/Bitmap/tga.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include<hgl/2d/TGA.h>
|
||||||
|
|
||||||
|
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
|
Loading…
x
Reference in New Issue
Block a user