本篇开始我们将学习所有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的两个简单运用,后面将继续演示其他函数的使用。
以上所有代码可在以下地址下载: