Compare commits
10 Commits
ef84a87f23
...
8e746deb78
Author | SHA1 | Date | |
---|---|---|---|
8e746deb78 | |||
72fedd4f3c | |||
b64f4c90e4 | |||
fd7e7e3788 | |||
c73574da9f | |||
004bfa7e73 | |||
a5d8d578e7 | |||
04f182e78c | |||
24ab6f5f9f | |||
1c22233101 |
@ -1,8 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(CM2D)
|
||||
|
||||
include(path_config.cmake)
|
||||
CM2DSetup(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_subdirectory(${CM2D_ROOT_SOURCE_PATH})
|
||||
add_subdirectory(${CM2D_ROOT_SOURCE_PATH})
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define HGL_2D_BITMAP_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/type/String.h>
|
||||
#include<hgl/math/HalfFloat.h>
|
||||
#include<iterator>
|
||||
namespace hgl
|
||||
@ -17,7 +18,7 @@ namespace hgl
|
||||
/**
|
||||
* 简单的2D象素处理
|
||||
*/
|
||||
template<typename T> class Bitmap
|
||||
template<typename T,uint C> 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<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
|
||||
#endif//HGL_2D_BITMAP_INCLUDE
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
#include<hgl/type/DataType.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/*
|
||||
* 基于位图的字体
|
||||
*/
|
||||
class BitmapFont
|
||||
{
|
||||
uint bits;
|
||||
uint width,height;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
};//class BitmapFont
|
||||
}//namespace hgl
|
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(nullptr);
|
||||
|
||||
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
|
@ -27,7 +27,80 @@ namespace hgl
|
||||
{
|
||||
public:
|
||||
|
||||
void operator ()(const Bitmap<ST> *src,Bitmap<DT> *dst,const float alpha)const;
|
||||
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
|
||||
|
@ -1,19 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include<hgl/2d/Bitmap.h>
|
||||
#include<hgl/2d/blend.h>
|
||||
#include<hgl/2d/Blend.h>
|
||||
#include<hgl/math/FastTriangle.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace bitmap
|
||||
{
|
||||
template<typename T> class DrawGeometry
|
||||
template<typename T,typename FormatBitmap> class DrawGeometry
|
||||
{
|
||||
public:
|
||||
|
||||
using FormatBitmap=Bitmap<T>;
|
||||
|
||||
protected:
|
||||
|
||||
FormatBitmap *bitmap;
|
||||
@ -58,9 +54,9 @@ namespace hgl
|
||||
|
||||
bool GetPixel(int x,int y,T &color)
|
||||
{
|
||||
if(!data)return(false);
|
||||
if(!bitmap)return(false);
|
||||
|
||||
T *p=GetData(x,y);
|
||||
T *p=bitmap->GetData(x,y);
|
||||
|
||||
if(!p)return(false);
|
||||
|
||||
@ -82,6 +78,11 @@ namespace hgl
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool PutPixel(const Vector2i &v)
|
||||
{
|
||||
return PutPixel(v.x,v.y);
|
||||
}
|
||||
|
||||
bool DrawHLine(int x,int y,int length)
|
||||
{
|
||||
if(!bitmap)return(false);
|
||||
@ -121,7 +122,7 @@ namespace hgl
|
||||
|
||||
if(w<=0||h<=0)return(false);
|
||||
|
||||
T *p=bitmap->GetData(x,y);
|
||||
T *p=bitmap->GetData(l,t);
|
||||
|
||||
for(int y=t;y<t+h;y++)
|
||||
{
|
||||
@ -343,11 +344,16 @@ namespace hgl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawLine(const Vector2i &start,const Vector2i &end)
|
||||
{
|
||||
DrawLine(start.x,start.y,end.x,end.y);
|
||||
}
|
||||
|
||||
void DrawSector(int x0, int y0, uint r, uint stangle, uint endangle)
|
||||
{
|
||||
int i, j;
|
||||
int *xy;
|
||||
AutoDeleteArray<int> xy(20);
|
||||
int bx, ex, bxd, exd, bxf, exf, ben;
|
||||
int tn, x, y;
|
||||
int xmax;
|
||||
@ -356,7 +362,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 +442,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)
|
||||
@ -478,5 +482,9 @@ namespace hgl
|
||||
}
|
||||
}
|
||||
};//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); ///<TGA文件头,必须等于18
|
||||
|
||||
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