SimpleCG绘图函数(1)

本文介绍了SimpleCG库中用于绘制像素的putpixel和getpixel函数,它们是构建点阵图的基础。文章通过代码示例展示了如何使用这两个函数创建粒子系统模拟烟花效果以及绘制色板并获取颜色。这些基本函数在计算机图形学中至关重要,可以组合出各种复杂的图像。
摘要由CSDN通过智能技术生成

        本篇开始我们将学习所有SimpleCG库支持的绘图函数,首先我们来学习最简单也最基础的函数putpixel和getpixel。这两个函数虽然简单,但功能却不容忽视,因为所有计算机呈现出来的图片都是点阵图,也叫像素图.而这两个函数就是画点和获取点颜色的,也就是理论上有这两个函数就可以把所有图片绘画出来。

        函数定义如下:

1、画点

//在坐标(nX,nY)处以32位颜色值nColor绘制一个点
void putpixel( int nX, int nY, COLORREF nColor );


2、获取某点颜色

//获取点(nX,nY)处的32位颜色值
COLORREF getpixel( int nX, int nY );

下面通过两个代码演示其使用方法:

代码一,通过简单粒子系统演示烟花效果的代码示例:

程序通过擦除背景,然后通过动态在指定位置将粒子颜色绘制到屏幕,达到烟花上升及爆炸的效果,充分展示了putpixel在绘画中的作用。只要算法能计算出屏幕相应点的颜色就能绘制任何图形。

// Fireworks.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "../import/include/CGBoard.h"
#include "math.h"
#pragma comment(lib,"../import/lib/SimpleCG.lib")
#define PARTICAL_CNT 500
#define UPSPEED -35
#define DOWNACCESSY 1

int g_nWidth = 600;
int g_nHeight= 700;
typedef struct _tagPartical
{
	POINT ptPosCur;		//当前位置
	float fVx;			//速度x
	float fVy;			//速度y
	float fAccessX;		//加速度X
	float fAccessY;		//加速度Y
	float fDir;			//方向
	COLORREF nColor;	//颜色
}tagPartical;

typedef struct _tagEmitter
{
	POINT ptPosCur;		//当前位置
	float fVx;			//速度x
	float fVy;			//速度y
	float fAccessX;		//加速度X
	float fAccessY;		//加速度Y
	float fDir;			//方向
	COLORREF nColor;	//颜色
	int nType;			//发射器类型
	tagPartical pPartical[PARTICAL_CNT];
}tagEmitter;
enum ENUM_EMITTERTYPE
{
	UPLOAD
	, BOOM
};
COLORREF RGBAdd(COLORREF nColor,int n)
{
	int r,g,b;
	r=GetRValue(nColor);
	g=GetGValue(nColor);
	b=GetBValue(nColor);

	r += n;
	if(r<0)
		r=0;
	else if(r>255)
		r=255;
	g += n;
	if(g<0)
		g=0;
	else if(g>255)
		g=255;
	b += n;
	if(b<0)
		b=0;
	else if(b>255)
		b=255;
	return RGB(r,g,b);
}
void UpdateEmitter(tagEmitter *pEmitter )
{
	int r,g,b;
	int nLen=0;
	pEmitter->ptPosCur.x += pEmitter->fVx;
	pEmitter->ptPosCur.y += pEmitter->fVy;
	pEmitter->fVx += pEmitter->fAccessX;
	pEmitter->fVy += pEmitter->fAccessY;

	for(int i=0;i<PARTICAL_CNT;++i)
	{
		pEmitter->pPartical[i].ptPosCur.x += pEmitter->pPartical[i].fVx;
		pEmitter->pPartical[i].ptPosCur.y += pEmitter->pPartical[i].fVy;
		pEmitter->pPartical[i].fVx += pEmitter->pPartical[i].fAccessX;
		pEmitter->pPartical[i].fVy += pEmitter->pPartical[i].fAccessY;

		if(pEmitter->pPartical[i].nColor == 0&&pEmitter->nType == UPLOAD)
		{
			nLen=rand()%50;
			pEmitter->pPartical[i].ptPosCur.x = pEmitter->ptPosCur.x+rand()%(nLen/3+1)-rand()%(nLen/3+1);
			pEmitter->pPartical[i].ptPosCur.y = pEmitter->ptPosCur.y+nLen;
			pEmitter->pPartical[i].nColor=RGBAdd(pEmitter->nColor, 100-nLen*2);
			if(rand()%7==5)
			{
				pEmitter->pPartical[i].fVy = -3;
				pEmitter->pPartical[i].fAccessY=1;
			}
		}
		if(pEmitter->nType == UPLOAD)
			pEmitter->pPartical[i].nColor=RGBAdd(pEmitter->pPartical[i].nColor, -rand()%30);
		else
			pEmitter->pPartical[i].nColor=RGBAdd(pEmitter->pPartical[i].nColor, -rand()%10);
	}
}
void RenderEmitter(tagEmitter *pEmitter)
{
	for(int i=0;i<PARTICAL_CNT;++i)
	{
		_putpixel(pEmitter->pPartical[i].ptPosCur.x,pEmitter->pPartical[i].ptPosCur.y,pEmitter->pPartical[i].nColor);
		/*setfillcolor(pEmitter->pPartical[i].nColor);
		_solidcircle(pEmitter->pPartical[i].ptPosCur.x,pEmitter->pPartical[i].ptPosCur.y,3);*/
	}
}
void InitBoom(tagEmitter *pEmitter)
{
	int nLen=0;
	int nV[3]={5,9,12};
	COLORREF nColor[3]={pEmitter->nColor,RGB(255-GetRValue(pEmitter->nColor),255-GetGValue(pEmitter->nColor),255-GetBValue(pEmitter->nColor)),pEmitter->nColor};
	pEmitter->nType = BOOM;
	pEmitter->fAccessX=0;
	/*pEmitter->fAccessY=0;*/
	for(int i=0;i<PARTICAL_CNT;++i)
	{
		nLen=rand()%300;
		pEmitter->pPartical[i].ptPosCur.x = pEmitter->ptPosCur.x;
		pEmitter->pPartical[i].ptPosCur.y = pEmitter->ptPosCur.y;
		pEmitter->pPartical[i].fVy = nV[nLen%3]*sin((float)(nLen%300)/300*2*C_PI);
		pEmitter->pPartical[i].fVx = nV[nLen%3]*cos((float)(nLen%300)/300*2*C_PI);
		pEmitter->pPartical[i].fAccessX=0;
		pEmitter->pPartical[i].fAccessY=1;
		pEmitter->pPartical[i].nColor=RGBAdd(nColor[nLen%3], 50+nV[nLen%3]*2);
	}
}
void InitUp(tagEmitter *pEmitter)
{
	int nLen=0;
	pEmitter->nType = UPLOAD;
	pEmitter->ptPosCur.x=100+rand()%300;
	pEmitter->ptPosCur.y=700;
	pEmitter->fAccessX=0;
	pEmitter->fAccessY=DOWNACCESSY;
	pEmitter->fVy = UPSPEED+rand()%10;
	pEmitter->fVx = 0;
	pEmitter->nColor = RGB(rand()%255,rand()%255,rand()%255);
	for(int i=0;i<PARTICAL_CNT;++i)
	{
		nLen=rand()%50;
		pEmitter->pPartical[i].ptPosCur.x = pEmitter->ptPosCur.x+rand()%(nLen/3+1)-rand()%(nLen/3+1);
		pEmitter->pPartical[i].ptPosCur.y = pEmitter->ptPosCur.y+nLen;
		pEmitter->pPartical[i].fVx = pEmitter->fVx;
		pEmitter->pPartical[i].fVy = pEmitter->fVy;
		pEmitter->pPartical[i].fAccessX=pEmitter->fAccessX;
		pEmitter->pPartical[i].fAccessY=pEmitter->fAccessY;
		pEmitter->pPartical[i].nColor=RGBAdd(pEmitter->nColor, 100-nLen*2);
		if(rand()%5<=1)
		{
			pEmitter->pPartical[i].nColor=rand()%100;
		}
	}
}
COLORREF GetBlurColor(int x,int y,int nStep)
{
	int i;
	int j;
	int r=0,g=0,b=0;
	COLORREF nColor=0;
	int nCount=0;
	for(j=y-nStep;j<y+nStep;++j)
	{
		for(i=x-nStep;i<x+nStep;++i)
		{
			nColor = _getpixel(i,j);
			r += GetRValue(nColor);
			g += GetGValue(nColor);
			b += GetBValue(nColor);
			++nCount;
		}
	}

	if(nCount>0)
	{
		r = r/nCount;
		g = g/nCount;
		b = b/nCount;
	}
	return RGB(r,g,b);
}
void DrawProcess()
{
	int x,y;
	int i=0;
	tagEmitter oEmitter[3];
	InitUp(&oEmitter[0]);
	InitUp(&oEmitter[1]);
	InitUp(&oEmitter[2]);
	while(true)
	{
		setfillcolor(0);
		_fillrectangle(0,0,g_nWidth,g_nHeight);
		for(i=0;i<3;++i)
		{
			UpdateEmitter(&oEmitter[i]);
			RenderEmitter(&oEmitter[i]);
		}
		ReflushWindow();
		Sleep(100);
		for(i=0;i<3;++i)
		{
			if(oEmitter[i].ptPosCur.y>g_nHeight)
				InitUp(&oEmitter[i]);
			else if(oEmitter[i].fVy>=0&&oEmitter[i].nType == UPLOAD)
				InitBoom(&oEmitter[i]);
		}
		
	}

}
int _tmain(int argc, _TCHAR* argv[])
{
	if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))
		return 1;
	CloseBoard();
	return 0;
}

运行图:

 

只要更改其中的粒子运动轨迹,相信你能创作出更加绚烂逼真的烟花效果,马上动手试试吧。

代码2:绘制一个色板并用代码获取指定位置颜色

// ColorPanel.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "../import/include/CGBoard.h"
#include "math.h"

#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MD.lib")
#endif
int g_nWidth = 600;
int g_nHeight= 300;



void DrawPanel()
{
	int x,y;
	int r,g,b=0;
	for(r=0;r<=255;++r)
	{
		y = r;
		x = 255;
		for(g=0;g<=255;++g)
		{
			_putpixel(x,y,RGB(r,g,b));
			--x;
		}
		x = 255;
		for(b=0;b<=255;++b)
		{
			_putpixel(x,y,RGB(r,g,b));
			++x;
		}	
	}
}
void DrawProcess()
{
	int x,y;
	bool bIsRunning = true;
	COLORREF nColor=0;
	DrawPanel();
	while(bIsRunning)
	{
		ReflushWindow();
		printf("please input x,y:\n");
		scanf("%d,%d",&x,&y);
		nColor = getpixel(x,y);
		printf("Point(%d,%d) color is RGB(%d,%d,%d):\n",x,y,GetRValue(nColor),GetGValue(nColor),GetBValue(nColor));
		ReflushWindow();

	}

}
int _tmain(int argc, _TCHAR* argv[])
{
	if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))
		return 1;
	CloseBoard();
	return 0;
}

运行图

 以上就是putpixel和getpixel的两个简单运用,后面将继续演示其他函数的使用。

以上所有代码可在以下地址下载:

b2b160 / SimpleCG_Demo · GitCode

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

b2b160

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值