示例#1
0
Handle<Bitmap> Bitmap::Clone() {
    Bitmap *b = new Bitmap(w, h);
    std::memcpy(b->GetPixels(), pixels,
                static_cast<std::size_t>(w * h * 4));
    return Handle<Bitmap>(b, false);
}
示例#2
0
		void SWModelRenderer::RenderInner(spades::draw::SWModel *model,
									 const client::ModelRenderParam &param) {
			auto& mat = param.matrix;
			auto origin = mat.GetOrigin();
			auto axis1 = mat.GetAxis(0);
			auto axis2 = mat.GetAxis(1);
			auto axis3 = mat.GetAxis(2);
			auto *rawModel = model->GetRawModel();
			auto rawModelOrigin = rawModel->GetOrigin();
			rawModelOrigin += 0.1f;
			origin += axis1 * rawModelOrigin.x;
			origin += axis2 * rawModelOrigin.y;
			origin += axis3 * rawModelOrigin.z;
			
			int w = rawModel->GetWidth();
			int h = rawModel->GetHeight();
			//int d = rawModel->GetDepth();
			
			// evaluate brightness for each normals
			uint8_t brights[3*3*3];
			{
				auto lightVec = MakeVector3(0.f, -0.707f, -0.707f);
				float dot1 = Vector3::Dot(axis1, lightVec) * fastRSqrt(axis1.GetPoweredLength());
				float dot2 = Vector3::Dot(axis2, lightVec) * fastRSqrt(axis2.GetPoweredLength());
				float dot3 = Vector3::Dot(axis3, lightVec) * fastRSqrt(axis3.GetPoweredLength());
				for(int x = 0; x < 3; x++){
					float d;
					int cnt;
					switch(x){
						case 0: d = -dot1; cnt = 1; break;
						case 1: d = 0.f; cnt = 0; break;
						case 2: d = dot1; cnt = 1; break;
					}
					for(int y = 0; y < 3; y++){
						auto d2 = d;
						auto cnt2 = cnt;
						switch(y){
							case 0: d2 -= dot2; cnt2++; break;
							case 1: break;
							case 2: d2 += dot2; cnt2++; break;
						}
						for(int z = 0; z < 3; z++) {
							auto d3 = d;
							auto cnt3 = cnt2;
							switch(y){
								case 0: d3 -= dot3; cnt3++; break;
								case 1: break;
								case 2: d3 += dot3; cnt3++; break;
							}
							switch(cnt3){
								case 2:
									d3 *= 0.707f;
									break;
								case 3:
									d3 *= 0.57735f;
									break;
							}
							d3 = 192.f + d3 * 62.f;
							brights[x + y * 3 + z * 9]
							= static_cast<uint8_t>(d3);
						}
					}
				}
			}
				
			
			// compute center coord. for culling
			{
				auto center = origin;
				auto localCenter = model->GetCenter();
				center += axis1 * localCenter.x;
				center += axis2 * localCenter.y;
				center += axis3 * localCenter.z;
				
				float largestAxis = axis1.GetPoweredLength();
				largestAxis = std::max(largestAxis, axis2.GetPoweredLength());
				largestAxis = std::max(largestAxis, axis3.GetPoweredLength());
				
				if(!r->SphereFrustrumCull(center, model->GetRadius() * sqrtf(largestAxis)))
					return;
			}
			
			Bitmap *fbmp = r->fb;
			auto *fb = fbmp->GetPixels();
			int fw = fbmp->GetWidth();
			int fh = fbmp->GetHeight();
			auto *db = r->depthBuffer.data();
			
			Matrix4 viewproj = r->GetProjectionViewMatrix();
			Vector4 ndc2scrscale = {fw * 0.5f, -fh * 0.5f, 1.f, 1.f};
			//Vector4 ndc2scroff = {fw * 0.5f, fh * 0.5f, 0.f, 0.f};
			int ndc2scroffX = fw >> 1;
			int ndc2scroffY = fh >> 1;
			
			
			// render each points
			auto tOrigin = viewproj * MakeVector4(origin.x, origin.y, origin.z, 1.f);
			auto tAxis1 = viewproj * MakeVector4(axis1.x, axis1.y, axis1.z, 0.f);
			auto tAxis2 = viewproj * MakeVector4(axis2.x, axis2.y, axis2.z, 0.f);
			auto tAxis3 = viewproj * MakeVector4(axis3.x, axis3.y, axis3.z, 0.f);
			tOrigin *= ndc2scrscale;
			tAxis1 *= ndc2scrscale;
			tAxis2 *= ndc2scrscale;
			tAxis3 *= ndc2scrscale;
			
			float pointDiameter;// = largestAxis * 0.55f * fh * 0.5f;
			{
				float largestAxis = tAxis1.GetPoweredLength();
				largestAxis = std::max(largestAxis, tAxis2.GetPoweredLength());
				largestAxis = std::max(largestAxis, tAxis3.GetPoweredLength());
				pointDiameter = sqrtf(largestAxis);
			}
			
			uint32_t customColor;
			customColor =
			ToFixed8(param.customColor.z) |
			(ToFixed8(param.customColor.y) << 8) |
			(ToFixed8(param.customColor.x) << 16);
			
			auto v1 = tOrigin;
			float zNear = r->sceneDef.zNear;
			for(int x = 0; x < w; x++) {
				auto v2 = v1;
				for(int y = 0; y < h; y++) {
					auto *mp = &model->renderData
					[model->renderDataAddr[x + y * w]];
					while(*mp != -1) {
						uint32_t data = *(mp++);
						uint32_t normal = *(mp++);
						int z = static_cast<int>(data >> 24);
						//SPAssert(z < d);
						SPAssert(z >= 0);
						
						auto vv = v2 + tAxis3 * zvals[z];
						if(vv.z < zNear) continue;
						
						// save Z value (don't divide this by W!)
						float zval = vv.z;
						
						// use vv.z for point radius to be divided by W
						vv.z = pointDiameter;
						
						// perspective division
						float scl = fastRcp(vv.w);
						vv *= scl;
						
						int ix = static_cast<int>(vv.x) + ndc2scroffX;
						int iy = static_cast<int>(vv.y) + ndc2scroffY;
						int idm = static_cast<int>(vv.z + .99f);
						idm = std::max(1, idm);
						int minX = ix - (idm >> 1);
						int minY = iy - (idm >> 1);
						if(minX >= fw || minY >= fh) continue;
						int maxX = ix + idm;
						int maxY = iy + idm;
						if(maxX <= 0 || maxY <= 0) continue;
						
						minX = std::max(minX, 0);
						minY = std::max(minY, 0);
						maxX = std::min(maxX, fw);
						maxY = std::min(maxY, fh);
						
						auto *fb2 = fb + (minX + minY * fw);
						auto *db2 = db + (minX + minY * fw);
						int w = maxX - minX;
						
						uint32_t color = data & 0xffffff;
						if(color == 0)
							color = customColor;
						
						SPAssert(normal < 27);
						int bright = brights[normal];
#if ENABLE_SSE2
						if(lvl == SWFeatureLevel::SSE2) {
							auto m = _mm_setr_epi32(color, 0, 0, 0);
							auto f = _mm_set1_epi16(bright << 8);
							
							m = _mm_unpacklo_epi8(m, _mm_setzero_si128());
							m = _mm_mulhi_epu16(m, f);
							m = _mm_packus_epi16(m, m);
							
							_mm_store_ss(reinterpret_cast<float*>(&color),
										 _mm_castsi128_ps(m));
						}else
#endif
						{
							uint32_t c1 = color & 0xff00;
							uint32_t c2 = color & 0xff00ff;
							c1 *= bright;
							c2 *= bright;
							color = ((c1&0xff0000) | (c2&0xff00ff00)) >> 8;
						}
						
						for(int yy = minY; yy < maxY; yy++){
							auto *fb3 = fb2;
							auto *db3 = db2;
							
							for(int xx = w; xx > 0; xx--) {
								if(zval < *db3) {
									*db3 = zval;
									*fb3 = color;
								}
								fb3++; db3++;
							}
							
							fb2 += fw;
							db2 += fw;
						}
						
						
					}
					v2 += tAxis2;
				}
				v1 += tAxis1;
			}
		}
示例#3
0
文件: PNG.cpp 项目: ksnydertn/modplug
OPENMPT_NAMESPACE_BEGIN


PNG::Bitmap *PNG::ReadPNG(FileReader &file)
//-----------------------------------------
{
	file.Rewind();
	if(!file.ReadMagic("\211PNG\r\n\032\n"))
	{
		return nullptr;
	}

	uint32_t width = 0;
	uint32_t height = 0;
	uint8_t bitDepth;
	uint8_t colorType;
	uint8_t compressionMethod;
	uint8_t filterMethod;
	uint8_t interlaceMethod;

	std::vector<uint8_t> dataIn;
	std::vector<Pixel> palette;

	while(file.AreBytesLeft())
	{
		uint32_t chunkLength = file.ReadUint32BE();
		char magic[4];
		file.ReadArray(magic);
		FileReader chunk = file.ReadChunk(chunkLength);
		file.Skip(4);	// CRC32
		if(!memcmp(magic, "IHDR", 4))
		{
			// Image header
			width = chunk.ReadUint32BE();
			height = chunk.ReadUint32BE();
			bitDepth = chunk.ReadUint8();
			colorType = chunk.ReadUint8();
			compressionMethod = chunk.ReadUint8();
			filterMethod = chunk.ReadUint8();
			interlaceMethod = chunk.ReadUint8();
			ASSERT(!filterMethod && !interlaceMethod);
		} else if(!memcmp(magic, "IDAT", 4))
		{
			// Data block(s)
			z_stream strm;
			strm.zalloc = Z_NULL;
			strm.zfree = Z_NULL;
			strm.opaque = Z_NULL;
			strm.avail_in = static_cast<uInt>(chunk.GetLength());
			strm.next_in = (Bytef *)(chunk.GetRawData());
			if(inflateInit2(&strm, 15) != Z_OK)
			{
				break;
			}
			int retVal;
			do
			{
				dataIn.resize(dataIn.size() + 4096);
				strm.avail_out = 4096;
				strm.next_out = (Bytef *)&dataIn[dataIn.size() - 4096];
				retVal = inflate(&strm, Z_NO_FLUSH);
			} while(retVal == Z_OK);
			inflateEnd(&strm);
		} else if(!memcmp(magic, "PLTE", 4))
		{
			// Palette for <= 8-bit images
			palette.resize(256);
			size_t numEntries = std::min<size_t>(256u, chunk.GetLength() / 3u);
			for(size_t i = 0; i < numEntries; i++)
			{
				uint8_t p[3];
				chunk.ReadArray(p);
				palette[i] = Pixel(p[0], p[1], p[2], 255);
			}
		}
	}

	// LUT for translating the color type into a number of color samples
	const uint32_t sampleTable[] =
	{
		1,	// 0: Grayscale
		0,
		3,	// 2: RGB
		1,	// 3: Palette bitmap
		2,	// 4: Grayscale + Alpha
		0,
		4	// 6: RGBA
	};
	const uint32_t bitsPerPixel = colorType < CountOf(sampleTable) ? sampleTable[colorType] * bitDepth : 0;

	if(!width || !height || !bitsPerPixel
		|| (colorType != 2  && colorType != 3 && colorType != 6) || bitDepth != 8	// Only RGB(A) and 8-bit palette PNGs for now.
		|| compressionMethod || interlaceMethod
		|| (colorType == 3 && palette.empty())
		|| dataIn.size() < (bitsPerPixel * width * height) / 8 + height)			// Enough data present?
	{
		return nullptr;
	}

	Bitmap *bitmap = new (std::nothrow) Bitmap(width, height);

	Pixel *pixelOut = bitmap->GetPixels();
	uint32_t x = 0, y = 0;
	size_t offset = 0;
	while(y < height)
	{
		if(x == 0)
		{
			filterMethod = dataIn[offset++];
			ASSERT(!filterMethod);
		}

		if(colorType == 6)
		{
			// RGBA
			pixelOut->r = dataIn[offset++];
			pixelOut->g = dataIn[offset++];
			pixelOut->b = dataIn[offset++];
			pixelOut->a = dataIn[offset++];
		} else if(colorType == 2)
		{
			// RGB
			pixelOut->r = dataIn[offset++];
			pixelOut->g = dataIn[offset++];
			pixelOut->b = dataIn[offset++];
			pixelOut->a = 255;
		} else if(colorType == 3)
		{
			// Palette
			*pixelOut = palette[dataIn[offset++]];
		}
		pixelOut++;
		x++;

		if(x == width)
		{
			y++;
			x = 0;
		}
	}

	return bitmap;
}
示例#4
0
//DIB Methods
Value*
getViewportDib_cf(Value** arg_list, int count)
{
	check_arg_count(getViewportDib, 0, count);
	GraphicsWindow *gw = MAXScript_interface->GetActiveViewExp().getGW();
	BITMAPINFO *bmi = NULL;
	BITMAPINFOHEADER *bmih;
	BitmapInfo bi;
	Bitmap *bmp;
	int size;
	gw->getDIB(NULL, &size);
	bmi  = (BITMAPINFO *)malloc(size);
	bmih = (BITMAPINFOHEADER *)bmi;
	gw->getDIB(bmi, &size);
	bi.SetWidth((WORD)bmih->biWidth);
	bi.SetHeight((WORD)bmih->biHeight);
	bi.SetType(BMM_TRUE_32);

	UWORD  *gammatab = NULL;

	IColorCorrectionMgr* idispGamMgr = (IColorCorrectionMgr*) GetCOREInterface(COLORCORRECTIONMGR_INTERFACE);
	float gamma = 1.0f; // default if off
	if(gammaMgr.IsEnabled() && idispGamMgr)
	{
		gamma = idispGamMgr->GetGamma();
		gammatab = new UWORD[RCOLN];

		// Build gamma correction table
		if (gammatab)
			BuildGammaTab(gammatab, 1.0f/gamma, true);

		// To gamma-correct we need 64 bits resolution
		bi.SetType(BMM_TRUE_64);
	}

	bi.SetGamma(1.0f); // New bitmap will be linear

	bmp = CreateBitmapFromBitmapInfo(bi); // Make new, linear bitmap
	bmp->FromDib(bmi);

	free(bmi);    // JBW 10.7.99: missing free(), elided above I/O, not desired

	// If gamma is on:
	/* EXPLANATION:
		The code that saves a bitmap always assumes the bitmap to be saved comes from the renderer,
		and hence, is linear. Since we are grabbing off the viewport (with an embedded gamma) we
		need to linearize the bitmap first */
	if (gammatab)
	{
		// We still want this to be SAVED with a gamma. What gamma MaxScript will save
		// this with (by default) is defined by the gamma of the BitmapInfo bi's gamma
		// And we intentionally want it to look like it was displayed - hence we use the
		// display gamma!!
		bi.SetGamma(gamma);

		int h = bmp->Height();
		int w = bmp->Width();

		BMM_Color_64 *pixelrow = (BMM_Color_64 *)LocalAlloc(LPTR,w*sizeof(BMM_Color_64));

		if (pixelrow) 
		{
			for (int iy = 0; iy < h; iy++) {
				bmp->GetPixels(0, iy, w, pixelrow);
				for (int ix = 0; ix < w; ix++) {
					
					pixelrow[ix].r = gammatab[UWORD(pixelrow[ix].r) >> RCSH16];
					pixelrow[ix].g = gammatab[UWORD(pixelrow[ix].g) >> RCSH16];
					pixelrow[ix].b = gammatab[UWORD(pixelrow[ix].b) >> RCSH16];
				}
				bmp->PutPixels(0, iy, w, pixelrow);
			}
			LocalFree(pixelrow);
		}

		delete [] gammatab;
	}

	return new MAXBitMap(bi, bmp);
}