Example #1
0
void NearestSampler(PixelBox& dest, const PixelBox& src) {
	size_t bytesPerPix = BytesPerPixel(src.format);
	NEX_ASSERT(bytesPerPix == BytesPerPixel(dest.format));

	float dstep = ((float) src.GetDepth() / (float) dest.GetDepth()) * .5f;
	float hstep = ((float) src.GetHeight() / (float) dest.GetHeight()) * .5f;
	float wstep = ((float) src.GetWidth() / (float) dest.GetWidth()) * .5f;

	for (uint32 d = dest.front; d < dest.back; ++d) {
		size_t doff = (uint32) (dstep * (src.slicePixelPitch * d * 2 + 1));
		NEX_ASSERT(doff >= 0 && doff <= src.slicePixelPitch * d);
		void* destPlane = reinterpret_cast<uint8*>(dest.data)
				+ d * dest.slicePixelPitch * bytesPerPix;
		for (uint32 h = dest.top; h < dest.bottom; ++h) {

			size_t hoff = (uint32) ((2 * h * src.rowPixelPitch + 1) * hstep);
			NEX_ASSERT(hoff >= 0 && hoff <= src.rowPixelPitch * h);
			uint8* destRow = reinterpret_cast<uint8*>(destPlane)
					+ h * dest.rowPixelPitch * bytesPerPix;
			for (uint32 w = dest.left; w < dest.right; ++w) {
				size_t woff = (size_t) ((2 * w + 1) * wstep);
				NEX_ASSERT(woff >= 0 && woff <= w);
				uint8* srcData = reinterpret_cast<uint8*>(src.data)
						+ (doff + hoff + woff) * bytesPerPix;
				// src offset
				uint8* destData = (destRow + w * bytesPerPix);
				for (uint32 j = 0; j < bytesPerPix; ++j)
					destData[j] = srcData[j];
			}
		}
	}
}
Example #2
0
void TextureViewGL::Update(nextar::RenderContext* rc, uint32 msg,
	ContextObject::ContextParamPtr params) {

	RenderContext_Base_GL* gl = static_cast<RenderContext_Base_GL*>(rc);
	if (msg & TextureBase::MSG_TEX_READ) {
		ReadPixels(gl, *const_cast<TextureBase::ReadPixelUpdateParams*>(
			reinterpret_cast<const TextureBase::ReadPixelUpdateParams*>(params)));
		return;
	}

	// todo Incorrect implementation
	if (msg & (TextureBase::MSG_TEX_CREATE|TextureBase::MSG_TEX_UPLOAD)) {
		const TextureBase::UpdateParams& textureParams =
				*reinterpret_cast<const TextureBase::UpdateParams*>(params);

		PixelFormat imageFormat = textureParams.textureFormat;
		if (textureParams.image)
			imageFormat = textureParams.image->GetFormat();

		if (!IsCreated()) {
			pixelFormat = RenderContext_Base_GL::GetGlPixelFormat(imageFormat,
					textureParams.textureFormat);

			if (pixelFormat.internalFormat == GL_NONE) {
				Warn(
						"Currently image should be of compatible format with texture!");
				return;
			}

			texture = gl->CreateTexture();
			target = RenderContext_Base_GL::GetGlTextureType(
					textureParams.type);
			gl->ActivateTexture(target, texture);

			if (textureParams.textureFlags
					& TextureBase::PRE_ALLOCATE_STORAGE) {
				gl->AllocateTexture(target,
						(GLint) textureParams.desc.maxMipMapCount,
						pixelFormat.internalFormat, textureParams.desc.maxWidth,
						textureParams.desc.maxHeight,
						textureParams.desc.maxDepth);
			}
		} else
			gl->ActivateTexture(target, texture);

		if (textureParams.image && (msg & TextureBase::MSG_TEX_UPLOAD)) {
			Image& img = *textureParams.image;
			uint32 numMips = img.GetNumMipMaps();
			uint32 numFaces = img.GetNumFaces();
			NEX_ASSERT(numFaces == 1 || numFaces == 6);
			GLenum realTarget = target;
			if (target == GL_TEXTURE_CUBE_MAP
					|| target == GL_TEXTURE_CUBE_MAP_ARRAY)
				realTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
			for (uint32 f = 0; f < numFaces; ++f) {
				for (uint32 i = 0; i < numMips; ++i) {
					PixelBox box = img.GetPixelBox(f, i);
					if (!box.IsSimpleArray()) {
						Warn("Pixel box has pixel padding. Cannot copy.");
						continue;
					}
					if (textureParams.textureFlags
							& TextureBase::PRE_ALLOCATE_STORAGE)
						gl->WriteTextureLevel(realTarget + f,
								(GLint) (textureParams.baseMipLevel + i),
								pixelFormat, box.GetWidth(), box.GetHeight(),
								box.GetDepth(), box.data, box.GetDataSize());
					else
						gl->AllocateTextureLevel(realTarget + f,
								(GLint) (textureParams.baseMipLevel + i),
								pixelFormat, box.GetWidth(), box.GetHeight(),
								box.GetDepth(), box.data, box.GetDataSize());

				}
				gl->SetMipLevels(realTarget + f, textureParams.baseMipLevel,
						textureParams.lowestMipLevel);
			}
			// update number of mip levels
		}
	}
	else if (msg & TextureBase::MSG_TEX_RESIZE) {
		if (IsCreated())
			gl->DestroyTexture(texture);

		const TextureBase::ResizeParams& textureParams =
						*reinterpret_cast<const TextureBase::ResizeParams*>(params);

		texture = gl->CreateTexture();
		gl->ActivateTexture(target, texture);
		gl->AllocateTexture(target,
								(GLint) textureParams.desc.maxMipMapCount,
								pixelFormat.internalFormat, textureParams.desc.maxWidth,
								textureParams.desc.maxHeight,
								textureParams.desc.maxDepth);

	}

}
Example #3
0
void LinearSampler(PixelBox& dest, const PixelBox& src) {

	NEX_ASSERT(src.format == dest.format);
	size_t bytesPerPix = BytesPerPixel(src.format);
	size_t numChannels =
			formatDescTable[static_cast<uint32>(src.format)].numChannels;
	NEX_ASSERT(bytesPerPix == BytesPerPixel(dest.format));
	float dstep = ((float) src.GetDepth() / (float) dest.GetDepth()) * .5f;
	float hstep = ((float) src.GetHeight() / (float) dest.GetHeight()) * .5f;
	float wstep = ((float) src.GetWidth() / (float) dest.GetWidth()) * .5f;

	for (uint32 d = dest.front; d < dest.back; ++d) {
		float fdoff1 = (float) (dstep * (d * 2 + 1));
		size_t doff1 = (size_t) Math::Floor(fdoff1);
		size_t doff2 = std::min(doff1 + 1, (size_t) (src.back - 1));
		float dweight = fdoff1 - (float) doff1;
		float dweightOpp = 1 - dweight;

		NEX_ASSERT(doff1 >= src.front && doff1 < src.back);
		void* destPlane = reinterpret_cast<uint8*>(dest.data)
				+ d * dest.slicePixelPitch * bytesPerPix;
		for (uint32 h = dest.top; h < dest.bottom; ++h) {

			float fhoff1 = (float) ((2 * h + 1) * hstep);
			size_t hoff1 = (size_t) Math::Floor(fdoff1);
			size_t hoff2 = std::min(hoff1 + 1, (size_t) (src.bottom - 1));
			float hweight = fhoff1 - (float) hoff1;
			float hweightOpp = 1 - hweight;

			NEX_ASSERT(hoff1 >= src.top && hoff1 < src.bottom);
			uint8* destRow = reinterpret_cast<uint8*>(destPlane)
					+ h * dest.rowPixelPitch * bytesPerPix;
			for (uint32 w = dest.left; w < dest.right; ++w) {
				float fwoff1 = (2 * w + 1) * wstep;
				size_t woff1 = (size_t) Math::Floor(fwoff1);
				size_t woff2 = std::min(woff1 + 1, (size_t) (src.right - 1));
				float wweight = fwoff1 - (float) woff1;
				float wweightOpp = 1 - wweight;
				NEX_ASSERT(woff1 >= src.left && woff1 < src.right);
				// 
				ColorChannel d1h1w1, d1h1w2, d2h1w1, d2h1w2, d2h2w2, d2h2w1,
						d1h2w2, d1h2w1, accum;
				// extract

#define PIXVAL_EXTRACT(to, x,y,z)  \
_PackPixel( to, reinterpret_cast<uint8*>(src.data) + \
(x*src.slicePixelPitch + y*src.rowPixelPitch + z)*bytesPerPix, src.format);

				PIXVAL_EXTRACT(d1h1w1, doff1, hoff1, woff1);
				PIXVAL_EXTRACT(d1h1w2, doff1, hoff1, woff2);
				PIXVAL_EXTRACT(d2h1w1, doff2, hoff1, woff1);
				PIXVAL_EXTRACT(d2h1w2, doff2, hoff1, woff2);
				PIXVAL_EXTRACT(d2h2w2, doff2, hoff2, woff2);
				PIXVAL_EXTRACT(d2h2w1, doff2, hoff2, woff1);
				PIXVAL_EXTRACT(d1h2w2, doff1, hoff2, woff2);
				PIXVAL_EXTRACT(d1h2w1, doff1, hoff2, woff1);

				// src offset
				for (uint32 i = 0; i < numChannels; ++i) {
					accum.value[i] = d1h1w1.value[i]
							* (dweightOpp * hweightOpp * wweightOpp)
							+ d1h1w2.value[i]
									* (dweightOpp * hweightOpp * wweight)
							+ d2h1w1.value[i]
									* (dweight * hweightOpp * wweightOpp)
							+ d2h1w2.value[i] * (dweight * hweightOpp * wweight)
							+ d2h2w2.value[i] * (dweight * hweight * wweight)
							+ d2h2w1.value[i] * (dweight * hweight * wweightOpp)
							+ d1h2w2.value[i]
									* (dweight * hweightOpp * wweightOpp)
							+ d1h2w1.value[i]
									* (dweight * hweightOpp * wweight);
				}

				uint8* destData = destRow + w * bytesPerPix;
				_UnpackPixel(accum, destData, dest.format);
			}
		}
	}
}