⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pixmap.cpp

📁 经典开源游戏glest的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

Pixmap2D::Pixmap2D(int w, int h, int components){
	init(w, h, components);
}

void Pixmap2D::init(int components){
	this->w= -1;
	this->h= -1;
	this->components= components;
	pixels= NULL;
}

void Pixmap2D::init(int w, int h, int components){
	this->w= w;
	this->h= h;
	this->components= components;
	pixels= new uint8[h*w*components];
}

Pixmap2D::~Pixmap2D(){
	delete [] pixels;
}

void Pixmap2D::load(const string &path){
	string extension= path.substr(path.find_last_of('.')+1);
	if(extension=="bmp"){
		loadBmp(path);
	}
	else if(extension=="tga"){
		loadTga(path);
	}
	else{
		throw runtime_error("Unknown pixmap extension: "+extension);
	}
}

void Pixmap2D::loadBmp(const string &path){
	
	PixmapIoBmp plb;
	plb.openRead(path);

	//init
	w= plb.getW();
	h= plb.getH();
	if(components==-1){
		components= 3;
	}
	if(pixels==NULL){
		pixels= new uint8[w*h*components]; 
	}

	//data
	plb.read(pixels, components);
}

void Pixmap2D::loadTga(const string &path){
	
	PixmapIoTga plt;
	plt.openRead(path);
	w= plt.getW();
	h= plt.getH();

	//header
	int fileComponents= plt.getComponents();

	//init
	if(components==-1){
		components= fileComponents;
	}
	if(pixels==NULL){
		pixels= new uint8[w*h*components]; 
	}

	//read data
	plt.read(pixels, components);
}

void Pixmap2D::save(const string &path){
	string extension= path.substr(path.find_last_of('.')+1);
	if(extension=="bmp"){
		saveBmp(path);
	}
	else if(extension=="tga"){
		saveTga(path);
	}
	else{
		throw runtime_error("Unknown pixmap extension: "+extension);
	}
}

void Pixmap2D::saveBmp(const string &path){
	PixmapIoBmp psb;
	psb.openWrite(path, w, h, components);
	psb.write(pixels);
}

void Pixmap2D::saveTga(const string &path){
	PixmapIoTga pst;
	pst.openWrite(path, w, h, components);
	pst.write(pixels);
}

void Pixmap2D::getPixel(int x, int y, uint8 *value) const{
	for(int i=0; i<components; ++i){
		value[i]= pixels[(w*y+x)*components+i];
	}
}

void Pixmap2D::getPixel(int x, int y, float32 *value) const{
	for(int i=0; i<components; ++i){
		value[i]= pixels[(w*y+x)*components+i]/255.f;
	}
}

void Pixmap2D::getComponent(int x, int y, int component, uint8 &value) const{
	value= pixels[(w*y+x)*components+component];
}

void Pixmap2D::getComponent(int x, int y, int component, float32 &value) const{
	value= pixels[(w*y+x)*components+component]/255.f;
}

//vector get
Vec4f Pixmap2D::getPixel4f(int x, int y) const{
	Vec4f v(0.f);
	for(int i=0; i<components && i<4; ++i){
		v.ptr()[i]= pixels[(w*y+x)*components+i]/255.f;
	}
	return v;
}

Vec3f Pixmap2D::getPixel3f(int x, int y) const{
	Vec3f v(0.f);
	for(int i=0; i<components && i<3; ++i){
		v.ptr()[i]= pixels[(w*y+x)*components+i]/255.f;
	}
	return v;
}

float Pixmap2D::getPixelf(int x, int y) const{
	return pixels[(w*y+x)*components]/255.f;
}

float Pixmap2D::getComponentf(int x, int y, int component) const{
	float c;
	getComponent(x, y, component, c);
	return c;
}

void Pixmap2D::setPixel(int x, int y, const uint8 *value){
	for(int i=0; i<components; ++i){
		pixels[(w*y+x)*components+i]= value[i];
	}
}

void Pixmap2D::setPixel(int x, int y, const float32 *value){
	for(int i=0; i<components; ++i){
		pixels[(w*y+x)*components+i]= static_cast<uint8>(value[i]*255.f);
	}
}

void Pixmap2D::setComponent(int x, int y, int component, uint8 value){
	pixels[(w*y+x)*components+component]= value;
}

void Pixmap2D::setComponent(int x, int y, int component, float32 value){
	pixels[(w*y+x)*components+component]= static_cast<uint8>(value*255.f);
}

//vector set
void Pixmap2D::setPixel(int x, int y, const Vec3f &p){
	for(int i=0; i<components  && i<3; ++i){
		pixels[(w*y+x)*components+i]= static_cast<uint8>(p.ptr()[i]*255.f);
	}
}

void Pixmap2D::setPixel(int x, int y, const Vec4f &p){
	for(int i=0; i<components && i<4; ++i){
		pixels[(w*y+x)*components+i]= static_cast<uint8>(p.ptr()[i]*255.f);
	}
}

void Pixmap2D::setPixel(int x, int y, float p){
	pixels[(w*y+x)*components]= static_cast<uint8>(p*255.f);
}

void Pixmap2D::setPixels(const uint8 *value){
	for(int i=0; i<w; ++i){
		for(int j=0; j<h; ++j){
			setPixel(i, j, value);
		}
	}
}
	
void Pixmap2D::setPixels(const float32 *value){
	for(int i=0; i<w; ++i){
		for(int j=0; j<h; ++j){
			setPixel(i, j, value);
		}
	}
}

void Pixmap2D::setComponents(int component, uint8 value){
	assert(component<components);
	for(int i=0; i<w; ++i){
		for(int j=0; j<h; ++j){
			setComponent(i, j, component, value);
		}
	}
}

void Pixmap2D::setComponents(int component, float32 value){
	assert(component<components);
	for(int i=0; i<w; ++i){
		for(int j=0; j<h; ++j){
			setComponent(i, j, component, value);
		}
	}
}

float splatDist(Vec2i a, Vec2i b){
	return (max(abs(a.x-b.x),abs(a.y- b.y)) + 3.f*a.dist(b))/4.f;
}

void Pixmap2D::splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixmap2D *leftDown, const Pixmap2D *rightDown){

	Random random;

	assert(components==3 || components==4);

	if(
		!doDimensionsAgree(leftUp) ||
		!doDimensionsAgree(rightUp) ||
		!doDimensionsAgree(leftDown) ||
		!doDimensionsAgree(rightDown))
	{
		throw runtime_error("Pixmap2D::splat: pixmap dimensions don't agree");
	}

	for(int i=0; i<w; ++i){
		for(int j=0; j<h; ++j){
			
			float avg= (w+h)/2.f;

			float distLu= splatDist(Vec2i(i, j), Vec2i(0, 0));
			float distRu= splatDist(Vec2i(i, j), Vec2i(w, 0));
			float distLd= splatDist(Vec2i(i, j), Vec2i(0, h));
			float distRd= splatDist(Vec2i(i, j), Vec2i(w, h));
			
			const float powFactor= 2.0f;
			distLu= pow(distLu, powFactor);
			distRu= pow(distRu, powFactor);
			distLd= pow(distLd, powFactor);
			distRd= pow(distRd, powFactor);
			avg= pow(avg, powFactor);

			float lu= distLu>avg? 0: ((avg-distLu))*random.randRange(0.5f, 1.0f);
			float ru= distRu>avg? 0: ((avg-distRu))*random.randRange(0.5f, 1.0f);
			float ld= distLd>avg? 0: ((avg-distLd))*random.randRange(0.5f, 1.0f);
			float rd= distRd>avg? 0: ((avg-distRd))*random.randRange(0.5f, 1.0f);
			
			float total= lu+ru+ld+rd;

			Vec4f pix= (leftUp->getPixel4f(i, j)*lu+
				rightUp->getPixel4f(i, j)*ru+
				leftDown->getPixel4f(i, j)*ld+
				rightDown->getPixel4f(i, j)*rd)*(1.0f/total);

			setPixel(i, j, pix);				
		}	
	}
}

void Pixmap2D::lerp(float t, const Pixmap2D *pixmap1, const Pixmap2D *pixmap2){
	if(
		!doDimensionsAgree(pixmap1) ||
		!doDimensionsAgree(pixmap2))
	{
		throw runtime_error("Pixmap2D::lerp: pixmap dimensions don't agree");
	}

	for(int i=0; i<w; ++i){
		for(int j=0; j<h; ++j){
			setPixel(i, j, pixmap1->getPixel4f(i, j).lerp(t, pixmap2->getPixel4f(i, j)));
		}
	}
}

void Pixmap2D::copy(const Pixmap2D *sourcePixmap){
	
	assert(components==sourcePixmap->getComponents());

	if(w!=sourcePixmap->getW() || h!=sourcePixmap->getH()){
		throw runtime_error("Pixmap2D::copy() dimensions must agree");
	}
	memcpy(pixels, sourcePixmap->getPixels(), w*h*sourcePixmap->getComponents());
}

void Pixmap2D::subCopy(int x, int y, const Pixmap2D *sourcePixmap){
	assert(components==sourcePixmap->getComponents());

	if(w<sourcePixmap->getW() && h<sourcePixmap->getH()){
		throw runtime_error("Pixmap2D::subCopy(), bad dimensions");
	}

	uint8 *pixel= new uint8[components];

	for(int i=0; i<sourcePixmap->getW(); ++i){
		for(int j=0; j<sourcePixmap->getH(); ++j){
			sourcePixmap->getPixel(i, j, pixel);
			setPixel(i+x, j+y, pixel);
		}
	}

	delete pixel;
}

bool Pixmap2D::doDimensionsAgree(const Pixmap2D *pixmap){
	return pixmap->getW() == w && pixmap->getH() == h;
}

// =====================================================
//	class Pixmap3D
// =====================================================

Pixmap3D::Pixmap3D(){
	w= -1;
	h= -1;
	d= -1;
	components= -1;
}

Pixmap3D::Pixmap3D(int w, int h, int d, int components){
	init(w, h, d, components);
}

Pixmap3D::Pixmap3D(int d, int components){
	init(d, components);
}

void Pixmap3D::init(int w, int h, int d, int components){
	this->w= w;
	this->h= h;
	this->d= d;
	this->components= components;
	pixels= new uint8[h*w*d*components];;
}

void Pixmap3D::init(int d, int components){
	this->w= -1;
	this->h= -1;
	this->d= d;
	this->components= components;
	pixels= NULL;
}

Pixmap3D::~Pixmap3D(){
	delete [] pixels;
}

void Pixmap3D::loadSlice(const string &path, int slice){
	string extension= path.substr(path.find_last_of('.')+1);
	if(extension=="bmp"){
		loadSliceBmp(path, slice);
	}
	else if(extension=="tga"){
		loadSliceTga(path, slice);
	}
	else{
		throw runtime_error("Unknown pixmap extension: "+extension);
	}
}

void Pixmap3D::loadSliceBmp(const string &path, int slice){

	PixmapIoBmp plb;
	plb.openRead(path);

	//init
	w= plb.getW();
	h= plb.getH();
	if(components==-1){
		components= 3;
	}
	if(pixels==NULL){
		pixels= new uint8[w*h*d*components]; 
	}

	//data
	plb.read(&pixels[slice*w*h*components], components);
}

void Pixmap3D::loadSliceTga(const string &path, int slice){
	PixmapIoTga plt;
	plt.openRead(path);

	//header
	int fileComponents= plt.getComponents();

	//init
	w= plt.getW();
	h= plt.getH();
	if(components==-1){
		components= fileComponents;
	}
	if(pixels==NULL){
		pixels= new uint8[w*h*d*components]; 
	}

	//read data
	plt.read(&pixels[slice*w*h*components], components);
}

// =====================================================
//	class PixmapCube
// =====================================================

void PixmapCube::init(int w, int h, int components){
	for(int i=0; i<6; ++i){
		faces[i].init(w, h, components);
	}
}
	
	//load & save
void PixmapCube::loadFace(const string &path, int face){
	faces[face].load(path);
}

void PixmapCube::loadFaceBmp(const string &path, int face){
	faces[face].loadBmp(path);
}

void PixmapCube::loadFaceTga(const string &path, int face){
	faces[face].loadTga(path);
}

}}//end namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -