OpenGL接口的基本实现4[转]

OpenGL接口的基本实现4[转]

目录

OpenGL接口的基本实现4[转]

绘制图片

去掉不想要的颜色

Alpha测试

Alpha混合

Alpha透明

绘制部分图像至指定区域

图像缩放

绘制图片

void    drawImage(int startX, int startY, int w, int h)
{
	//判断是否越界
	int left = tmax<int>(startX, 0);
	int top = tmax<int>(startY, 0);

	int right = tmin<int>(startX + w, _width);
	int bottom = tmin<int>(startY + h, _height);

	for (int x = left; x < right; ++x)
	{
		for (int y = top; y < bottom; ++y)
		{
			//产生随机颜色值
			Rgba    color(rand() % 256, rand() % 256, rand() % 256);
			setPixelEx(x, y, color);
		}
	}
}
  • 使用FreeImage加载图片:
Image*    Image::loadFromFile(const char* fileName)
{
    //1 获取图片格式
    FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
    if (fifmt == FIF_UNKNOWN)
    {
        return  0;
    }
    //2 加载图片
    FIBITMAP    *dib = FreeImage_Load(fifmt, fileName,0);

    FREE_IMAGE_COLOR_TYPE type    =   FreeImage_GetColorType(dib);

    //! 获取数据指针
    FIBITMAP*   temp    =   dib;
    dib =   FreeImage_ConvertTo32Bits(dib);
    FreeImage_Unload(temp);

    BYTE*   pixels  =   (BYTE*)FreeImage_GetBits(dib);
    int     width   =   FreeImage_GetWidth(dib);
    int     height  =   FreeImage_GetHeight(dib);

    Image*  image   =   new Image(width,height,pixels);

    FreeImage_Unload(dib);
    return  image;
}
  • 封装图像类
class   Image
{
protected:
	int     _width;
	int     _height;
	uint*   _pixel;
public:
	Image(int w, int h, void* data)
	{
		if (w == 0 || h == 0 || data == 0)
		{
			_width = 0;
			_height = 0;
			_pixel = 0;
		}
		else
		{
			_width = w;
			_height = h;
			_pixel = new uint[w * h];   //颜色是RGBA 32bit,采用uint记录
			memcpy(_pixel, data, w * h * sizeof(uint));
		}
	}
	~Image()
	{
		delete[]_pixel;
	}

	int     width() const
	{
		return  _width;
	}
	int     height() const
	{
		return  _height;
	}

	Rgba    pixelAt(int x, int y) const
	{
		return  Rgba(_pixel[y * _width + x]);
	}

public:
	static  Image*  loadFromFile(const char*);
};
  • 【注:】使用共用体提升效率,只用赋值一次
union
{
	struct
	{

		unsigned char   _b;
		unsigned char   _g;
		unsigned char   _r;
		unsigned char   _a;
	};
	uint    _color;
};

Rgba4Byte(uint rgba)
{
	_color = rgba;
}

去掉不想要的颜色

void Raster::drawImageWidthColorKey( int startX,int startY,const Image* image,Rgba key )
{
    int left    =   tmax<int>(startX,0);
    int top     =   tmax<int>(startY,0);

    int right   =   tmin<int>(startX + image->width(),_width);
    int bottom  =   tmin<int>(startY + image->height(),_height);

    for (int x = left ; x <  right ; ++ x)
    {
        for (int y = top ; y <  bottom ; ++ y)
        {
            Rgba    color   =   image->pixelAt(x - left,y - top);
            if (color != key)
            {
                setPixelEx(x,y,color);
            }
        }
    }
}
  • 图像翻转180度(利用图片一行大小的缓存区,第一行和最后一行交换,依次类推)
int     pitch   =   width*4;
BYTE*   row     =   new BYTE[width*4];
for(int j = 0; j < height / 2; j++) 
{
    memcpy(row,pixels + j * pitch,pitch );

    memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );

    memcpy(pixels + (height - j - 1) * pitch,row,pitch );

}
delete  []row;

Alpha测试

  • 通过测试画或者不画
void    drawImageAlphaTest(int startX,int startY,const Image* image,byte alpha)
{
    int left    =   tmax<int>(startX,0);
    int top     =   tmax<int>(startY,0);

    int right   =   tmin<int>(startX + image->width(),_width);
    int bottom  =   tmin<int>(startY + image->height(),_height);

    for (int x = left ; x <  right ; ++ x)
    {
        for (int y = top ; y <  bottom ; ++ y)
        {
            Rgba    color   =   image->pixelAt(x - left,y - top);
            if (color._a < alpha)
            {
                setPixelEx(x,y,color);
            }
        }
    }
}

Alpha混合

  • 获取当前背景颜色:
inline  Rgba    getPixel(unsigned x,unsigned y)
{
    return  Rgba(_buffer[y * _width + x]);
}
void Raster::drawImageAlphaBlend( int startX,int startY,const Image* image,float alpha )
{
    int left    =   tmax<int>(startX,0);
    int top     =   tmax<int>(startY,0);

    int right   =   tmin<int>(startX + image->width(),_width);
    int bottom  =   tmin<int>(startY + image->height(),_height);

    for (int x = left ; x <  right ; ++ x)
    {
        for (int y = top ; y <  bottom ; ++ y)
        {
            Rgba    srcColor    =   image->pixelAt(x - left,y - top);
            Rgba    dstColor    =   getPixel(x,y);
            Rgba    color       =   colorLerp(dstColor,srcColor,srcColor._a/255.0f * alpha);
            setPixelEx(x,y,color);
        }
    }
}

Alpha透明

void    drawImageAlpha( int startX,int startY,const Image* image,float alpha )
{
    int left    =   tmax<int>(startX,0);
    int top     =   tmax<int>(startY,0);

    int right   =   tmin<int>(startX + image->width(),_width);
    int bottom  =   tmin<int>(startY + image->height(),_height);

    for (int x = left ; x <  right ; ++ x)
    {
        for (int y = top ; y <  bottom ; ++ y)
        {
            Rgba    srcColor    =   image->pixelAt(x - left,y - top);
            Rgba    dstColor    =   getPixel(x,y);
            Rgba    color       =   colorLerp(dstColor,srcColor,alpha);
            setPixelEx(x,y,color);
        }
    }
}

绘制部分图像至指定区域

void    drawImage(int startX,int startY,const Image* image,int x1,int y1,int w,int h)
{
    int left    =   tmax<int>(startX,0);
    int top     =   tmax<int>(startY,0);

    int right   =   tmin<int>(startX + w,_width);
    int bottom  =   tmin<int>(startY + h,_height);

    for (int x = left ; x <  right ; ++ x)
    {
        for (int y = top ; y <  bottom ; ++ y)
        {
            Rgba    srcColor    =   image->pixelAt(x - left + x1,y - top + y1);
            setPixelEx(x,y,srcColor);
        }
    }
}

图像缩放

void    drawImageScale(int dstX,int dstY,int dstW,int dstH,const Image* image)
{
    float   xScale  =   (float)image->width()/(float)dstW;
    float   yScale  =   (float)image->height()/(float)dstH;

    for (int x = dstX ;x <dstX + dstW ; ++ x )
    {
        for (int y = dstY ;y <dstY + dstH ; ++ y )
        {
            float   xx  =   (x - dstX) * xScale;
            float   yy  =   (y - dstY) * yScale;

            Rgba    srcColor    =   image->pixelAt(xx,yy);
            setPixelEx(x,y,srcColor);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值