bitmap.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 840 行 · 第 1/2 页
CPP
840 行
}
if ( numCounted != 0 )
{
aCol[a]=cCol/255.0f/numCounted;
}
}
for(int y=0;y<ysize;++y)
{
for(int x=0;x<xsize;++x)
{
if(mem[(y*xsize+x)*4+0]==red && mem[(y*xsize+x)*4+1]==green && mem[(y*xsize+x)*4+2]==blue) {
mem[(y*xsize+x)*4+0]= (unsigned char) (aCol.x*255);
mem[(y*xsize+x)*4+1]= (unsigned char) (aCol.y*255);
mem[(y*xsize+x)*4+2]= (unsigned char) (aCol.z*255);
mem[(y*xsize+x)*4+3]=0;
}
}
}
}
// Depreciated (Only used by GUI which will be replaced by CEGUI anyway)
void CBitmap::SetTransparent( unsigned char red, unsigned char green, unsigned char blue )
{
for ( unsigned int y = 0; y < xsize; y++ )
{
for ( unsigned int x = 0; x < xsize; x++ )
{
unsigned int index = (y*xsize + x)*4;
if ( mem[index+0] == red &&
mem[index+1] == green &&
mem[index+2] == blue )
{
// set transparent
mem[index+3] = 0;
}
}
}
}
void CBitmap::Renormalize(float3 newCol)
{
float3 aCol;
// float3 aSpread;
float3 colorDif;
// float3 spreadMul;
for(int a=0;a<3;++a){
int cCol=0;
int numCounted=0;
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
if(mem[(y*xsize+x)*4+3]!=0){
cCol+=mem[(y*xsize+x)*4+a];
++numCounted;
}
}
}
aCol[a]=cCol/255.0f/numCounted;
cCol/=xsize*ysize;
colorDif[a]=newCol[a]-aCol[a];
/* int spread=0;
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
if(mem[(y*xsize+x)*4+3]!=0){
int dif=mem[(y*xsize+x)*4+a]-cCol;
spread+=abs(dif);
}
}
}
aSpread.xyz[a]=spread/255.0f/numCounted;
spreadMul.xyz[a]=(float)(newSpread[a]/aSpread[a]);*/
}
for(int a=0;a<3;++a){
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
float nc=float(mem[(y*xsize+x)*4+a])/255.0f+colorDif[a];
/* float r=newCol.xyz[a]+(nc-newCol.xyz[a])*spreadMul.xyz[a];*/
mem[(y*xsize+x)*4+a]=(unsigned char)(std::min(255.f,std::max(0.f,nc*255)));
}
}
}
}
// Unused
CBitmap CBitmap::GetRegion(int startx, int starty, int width, int height)
{
CBitmap bm;
delete[] bm.mem;
bm.mem=SAFE_NEW unsigned char[width*height*4];
bm.xsize=width;
bm.ysize=height;
for(int y=0;y<height;++y){
for(int x=0;x<width;++x){
bm.mem[(y*width+x)*4]=mem[((starty+y)*xsize+startx+x)*4];
bm.mem[(y*width+x)*4+1]=mem[((starty+y)*xsize+startx+x)*4+1];
bm.mem[(y*width+x)*4+2]=mem[((starty+y)*xsize+startx+x)*4+2];
bm.mem[(y*width+x)*4+3]=mem[((starty+y)*xsize+startx+x)*4+3];
}
}
return bm;
}
CBitmap CBitmap::CreateMipmapLevel(void)
{
CBitmap bm;
delete[] bm.mem;
bm.xsize=xsize/2;
bm.ysize=ysize/2;
bm.mem=SAFE_NEW unsigned char[bm.xsize*bm.ysize*4];
for(int y=0;y<ysize/2;++y){
for(int x=0;x<xsize/2;++x){
float r=0,g=0,b=0,a=0;
for(int y2=0;y2<2;++y2){
for(int x2=0;x2<2;++x2){
r+=mem[((y*2+y2)*xsize+x*2+x2)*4+0];
g+=mem[((y*2+y2)*xsize+x*2+x2)*4+1];
b+=mem[((y*2+y2)*xsize+x*2+x2)*4+2];
a+=mem[((y*2+y2)*xsize+x*2+x2)*4+3];
}
}
bm.mem[(y*bm.xsize+x)*4]=(unsigned char)(r/4);
bm.mem[(y*bm.xsize+x)*4+1]=(unsigned char)(g/4);
bm.mem[(y*bm.xsize+x)*4+2]=(unsigned char)(b/4);
bm.mem[(y*bm.xsize+x)*4+3]=(unsigned char)(a/4);
}
}
return bm;
}
CBitmap CBitmap::CreateRescaled(int newx, int newy)
{
CBitmap bm;
delete[] bm.mem;
bm.xsize=newx;
bm.ysize=newy;
bm.mem=SAFE_NEW unsigned char[bm.xsize*bm.ysize*4];
float dx=float(xsize)/newx;
float dy=float(ysize)/newy;
float cy=0;
for(int y=0;y<newy;++y){
int sy=(int)cy;
cy+=dy;
int ey=(int)cy;
if(ey==sy)
ey=sy+1;
float cx=0;
for(int x=0;x<newx;++x){
int sx=(int)cx;
cx+=dx;
int ex=(int)cx;
if(ex==sx)
ex=sx+1;
int r=0,g=0,b=0,a=0;
for(int y2=sy;y2<ey;++y2){
for(int x2=sx;x2<ex;++x2){
r+=mem[(y2*xsize+x2)*4+0];
g+=mem[(y2*xsize+x2)*4+1];
b+=mem[(y2*xsize+x2)*4+2];
a+=mem[(y2*xsize+x2)*4+3];
}
}
bm.mem[(y*bm.xsize+x)*4+0]=r/((ex-sx)*(ey-sy));
bm.mem[(y*bm.xsize+x)*4+1]=g/((ex-sx)*(ey-sy));
bm.mem[(y*bm.xsize+x)*4+2]=b/((ex-sx)*(ey-sy));
bm.mem[(y*bm.xsize+x)*4+3]=a/((ex-sx)*(ey-sy));
}
}
return bm;
}
void CBitmap::InvertColors()
{
if (type != BitmapTypeStandardRGBA) {
return;
}
for(int y = 0; y < ysize; ++y) {
for(int x = 0; x < xsize; ++x) {
const int base = ((y * xsize) + x) * 4;
mem[base + 0] = 0xFF - mem[base + 0];
mem[base + 1] = 0xFF - mem[base + 1];
mem[base + 2] = 0xFF - mem[base + 2];
// do not invert alpha
}
}
}
void CBitmap::GrayScale()
{
if (type != BitmapTypeStandardRGBA) {
return;
}
for(int y = 0; y < ysize; ++y) {
for(int x = 0; x < xsize; ++x) {
const int base = ((y * xsize) + x) * 4;
const float illum =
(mem[base + 0] * 0.299f) +
(mem[base + 1] * 0.587f) +
(mem[base + 2] * 0.114f);
const unsigned int ival = (unsigned int)(illum * (256.0f / 255.0f));
const unsigned char cval = (ival <= 0xFF) ? ival : 0xFF;
mem[base + 0] = cval;
mem[base + 1] = cval;
mem[base + 2] = cval;
}
}
}
static ILubyte TintByte(ILubyte value, float tint)
{
float f = (float)value;
f = std::max(0.0f, std::min(255.0f, f * tint));
return (ILubyte)f;
}
void CBitmap::Tint(const float tint[3])
{
if (type != BitmapTypeStandardRGBA) {
return;
}
for (int y = 0; y < ysize; y++) {
for (int x = 0; x < xsize; x++) {
const int base = ((y * xsize) + x) * 4;
mem[base + 0] = TintByte(mem[base + 0], tint[0]);
mem[base + 1] = TintByte(mem[base + 1], tint[1]);
mem[base + 2] = TintByte(mem[base + 2], tint[2]);
// don't touch the alpha channel
}
}
}
void CBitmap::ReverseYAxis()
{
unsigned char* buf=SAFE_NEW unsigned char[xsize*ysize*4];
for(int y=0;y<ysize;++y){
for(int x=0;x<xsize;++x){
buf[((ysize-1-y)*xsize+x)*4+0]=mem[((y)*xsize+x)*4+0];
buf[((ysize-1-y)*xsize+x)*4+1]=mem[((y)*xsize+x)*4+1];
buf[((ysize-1-y)*xsize+x)*4+2]=mem[((y)*xsize+x)*4+2];
buf[((ysize-1-y)*xsize+x)*4+3]=mem[((y)*xsize+x)*4+3];
}
}
delete[] mem;
mem=buf;
}
#if defined(__APPLE__)
Handle CBitmap::GetPtrDataRef(unsigned char *data, unsigned int size,
const std::string &filename)
{
// Load Data Reference
Handle dataRef;
Handle fileNameHandle;
PointerDataRefRecord ptrDataRefRec;
ComponentInstance dataRefHandler;
unsigned char pstr[255];
ptrDataRefRec.data = data;
ptrDataRefRec.dataLength = size;
/*err = */PtrToHand(&ptrDataRefRec, &dataRef, sizeof(PointerDataRefRecord));
// Open a Data Handler for the Data Reference
/*err = */OpenADataHandler(dataRef, PointerDataHandlerSubType, NULL,
(OSType)0, NULL, kDataHCanRead, &dataRefHandler);
// Convert From CString in filename to a PascalString in pstr
if (filename.length() > 255) {
CopyCStringToPascal(filename.c_str(), pstr);
//hmm...not good, pascal string limit is 255!
//do some error handling maybe?!
}
// Add filename extension
/*err = */PtrToHand(pstr, &fileNameHandle, filename.length() + 1);
/*err = */DataHSetDataRefExtension(dataRefHandler, fileNameHandle,
kDataRefExtensionFileName);
DisposeHandle(fileNameHandle);
// Release old handler which does not have the extensions
DisposeHandle(dataRef);
// Grab the SAFE_NEW version of the data ref from the data handler
/*err = */ DataHGetDataRef(dataRefHandler, &dataRef);
return dataRef;
}
unsigned char *CBitmap::LoadTextureData(const std::string &filename,
unsigned char *data, unsigned int sizeData, int &xsize,
int &ysize, bool &hasAlpha)
{
unsigned char *imageData = 0;
GWorldPtr gworld = 0;
OSType pixelFormat;
int rowStride;
GraphicsImportComponent gicomp;
Rect rectImage;
GDHandle origDevice;
CGrafPtr origPort;
ImageDescriptionHandle desc;
int depth;
// Data Handle for file data ( & load data from file )
Handle dataRef = GetPtrDataRef(data, sizeData, filename);
// GraphicsImporter - Get Importer for our filetype
GetGraphicsImporterForDataRef(dataRef, 'ptr ', &gicomp);
// GWorld - Get Texture Info
if (noErr != GraphicsImportGetNaturalBounds(gicomp, &rectImage)) {
return 0;
}
xsize = (unsigned int)(rectImage.right - rectImage.left);
ysize = (unsigned int)(rectImage.bottom - rectImage.top);
// ImageDescription - Get Image Description
if (noErr != GraphicsImportGetImageDescription(gicomp, &desc)) {
CloseComponent(gicomp);
return 0;
}
// ImageDescription - Get Bit Depth
HLock(reinterpret_cast<char **>(desc));
if (depth == 32) { // Only if it returns 32 does the image have an alpha chanel!
hasAlpha = true;
} else {
hasAlpha = false;
}
// GWorld - Pixel Format stuff
pixelFormat = k32ARGBPixelFormat; // Make sure its forced...NOTE: i'm pretty sure this cannot be RGBA!
// GWorld - Row stride
rowStride = xsize * 4; // (width * depth_bpp / 8)
// GWorld - Allocate output buffer
imageData = SAFE_NEW unsigned char[rowStride * ysize];
// GWorld - Actually Create IT!
QTNewGWorldFromPtr(&gworld, pixelFormat, &rectImage, 0, 0, 0, imageData, rowStride);
if (!gworld) {
delete imageData;
CloseComponent(gicomp);
DisposeHandle(reinterpret_cast<char **>(desc));
return 0;
}
// Save old Graphics Device and Graphics Port to reset to later
GetGWorld (&origPort, &origDevice);
// GraphicsImporter - Set Destination GWorld (our buffer)
if (noErr != GraphicsImportSetGWorld(gicomp, gworld, 0)) {
DisposeGWorld(gworld);
delete imageData;
CloseComponent(gicomp);
DisposeHandle(reinterpret_cast<char **>(desc));
return 0;
}
// GraphicsImporter - Set Quality Level
if (noErr != GraphicsImportSetQuality(gicomp, codecLosslessQuality)) {
DisposeGWorld(gworld);
delete imageData;
CloseComponent(gicomp);
DisposeHandle(reinterpret_cast<char **>(desc));
return 0;
}
// Lock pixels so that we can draw to our memory texture
if (!GetGWorldPixMap(gworld) || !LockPixels(GetGWorldPixMap(gworld))) {
DisposeGWorld(gworld);
delete imageData;
CloseComponent(gicomp);
DisposeHandle(reinterpret_cast<char **>(desc));
return 0;
}
//*** Draw GWorld into our Memory Texture!
GraphicsImportDraw(gicomp);
// Clean up
UnlockPixels(GetGWorldPixMap(gworld));
SetGWorld(origPort, origDevice); // set graphics port to offscreen (we don't need it now)
DisposeGWorld(gworld);
CloseComponent(gicomp);
DisposeHandle(reinterpret_cast<char **>(desc));
return imageData;
}
#endif /* __APPLE__ */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?