Ejemplo n.º 1
0
//==============================================================================
Error Material::getProgramPipeline(
	const RenderingKey& key, GlPipelineHandle& out)
{
	ANKI_ASSERT(enumToType(key.m_pass) < m_passesCount);
	ANKI_ASSERT(key.m_lod < m_lodsCount);

	Error err = ErrorCode::NONE;

	U tessCount = 1;
	if(m_tessellation)
	{
		tessCount = 2;
	}
	else
	{
		ANKI_ASSERT(!key.m_tessellation);
	}

	U idx = enumToType(key.m_pass) * m_lodsCount * tessCount
		+ key.m_lod * tessCount + key.m_tessellation;

	GlPipelineHandle& ppline = m_pplines[idx];

	// Lazily create it
	if(ANKI_UNLIKELY(!ppline.isCreated()))
	{
		Array<GlShaderHandle, 5> progs;
		U progCount = 0;

		progs[progCount++] = 
			getProgram(key, ShaderType::VERTEX)->getGlProgram();

		if(key.m_tessellation)
		{
			progs[progCount++] = getProgram(
				key, ShaderType::TESSELLATION_CONTROL)->getGlProgram();
			progs[progCount++] = getProgram(
				key, ShaderType::TESSELLATION_EVALUATION)->getGlProgram();
		}

		progs[progCount++] = 
			getProgram(key, ShaderType::FRAGMENT)->getGlProgram();

		GlDevice& gl = m_resources->_getGlDevice();
		GlCommandBufferHandle cmdBuff;
		ANKI_CHECK(cmdBuff.create(&gl));

		ANKI_CHECK(ppline.create(cmdBuff, &progs[0], &progs[0] + progCount));

		cmdBuff.flush();
	}

	out = ppline;

	return err;
}
//==============================================================================
void TextureResource::loadInternal(const CString& filename, 
	ResourceInitializer& rinit)
{
	GlDevice& gl = rinit.m_resources._getGlDevice();
	GlCommandBufferHandle cmdb;
	cmdb.create(&gl); // Always first to avoid assertions (
	                  // because of the check of the allocator)

	GlTextureHandle::Initializer init;
	U layers = 0;
	Bool driverShouldGenMipmaps = false;

	// Load image
	Image* imgPtr = rinit.m_alloc.newInstance<Image>(rinit.m_alloc);
	Image& img = *imgPtr;
	img.load(filename, rinit.m_resources.getMaxTextureSize());
	
	// width + height
	init.m_width = img.getSurface(0, 0).m_width;
	init.m_height = img.getSurface(0, 0).m_height;
	
	// depth
	if(img.getTextureType() == Image::TextureType::_2D_ARRAY 
		|| img.getTextureType() == Image::TextureType::_3D)
	{
		init.m_depth = img.getDepth();
	}
	else
	{
		init.m_depth = 0;
	}

	// target
	switch(img.getTextureType())
	{
	case Image::TextureType::_2D:
		init.m_target = GL_TEXTURE_2D;
		layers = 1;
		break;
	case Image::TextureType::CUBE:
		init.m_target = GL_TEXTURE_CUBE_MAP;
		layers = 6;
		break;
	case Image::TextureType::_2D_ARRAY:
		init.m_target = GL_TEXTURE_2D_ARRAY;
		layers = init.m_depth;
		break;
	case Image::TextureType::_3D:
		init.m_target = GL_TEXTURE_3D;
		layers = init.m_depth;
	default:
		ANKI_ASSERT(0);
	}

	// Internal format
	if(img.getColorFormat() == Image::ColorFormat::RGB8)
	{
		switch(img.getCompression())
		{
		case Image::DataCompression::RAW:
#if DRIVER_CAN_COMPRESS
			init.m_internalFormat = GL_COMPRESSED_RGB;
#else
			init.m_internalFormat = GL_RGB;
#endif
			driverShouldGenMipmaps = true;
			break;
#if ANKI_GL == ANKI_GL_DESKTOP
		case Image::DataCompression::S3TC:
			init.m_internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
			break;
#else
		case Image::DataCompression::ETC:
			init.m_internalFormat = GL_COMPRESSED_RGB8_ETC2;
			break;
#endif
		default:
			ANKI_ASSERT(0);
		}
	}
	else if(img.getColorFormat() == Image::ColorFormat::RGBA8)
	{
		switch(img.getCompression())
		{
		case Image::DataCompression::RAW:
#if DRIVER_CAN_COMPRESS
			init.m_internalFormat = GL_COMPRESSED_RGBA;
#else
			init.m_internalFormat = GL_RGBA;
#endif
			driverShouldGenMipmaps = true;
			break;
#if ANKI_GL == ANKI_GL_DESKTOP
		case Image::DataCompression::S3TC:
			init.m_internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
			break;
#else
		case Image::DataCompression::ETC:
			init.m_internalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
			break;
#endif
		default:
			ANKI_ASSERT(0);
		}
	}
	else
	{
		ANKI_ASSERT(0);
	}

	// format
	switch(img.getColorFormat())
	{
	case Image::ColorFormat::RGB8:
		init.m_format = GL_RGB;
		break;
	case Image::ColorFormat::RGBA8:
		init.m_format = GL_RGBA;
		break;
	default:
		ANKI_ASSERT(0);
	}

	// type
	init.m_type = GL_UNSIGNED_BYTE;

	// mipmapsCount
	init.m_mipmapsCount = img.getMipLevelsCount();

	// filteringType
	init.m_filterType = GlTextureHandle::Filter::TRILINEAR;

	// repeat
	init.m_repeat = true;

	// anisotropyLevel
	init.m_anisotropyLevel = rinit.m_resources.getTextureAnisotropy();

	// genMipmaps
	if(init.m_mipmapsCount == 1 || driverShouldGenMipmaps)
	{
		init.m_genMipmaps = true;
	}
	else
	{
		init.m_genMipmaps = false;
	}

	// Now assign the data
	for(U layer = 0; layer < layers; layer++)
	{
		for(U level = 0; level < init.m_mipmapsCount; level++)
		{
			GlClientBufferHandle& buff = init.m_data[level][layer];

			buff.create(
				cmdb, 
				img.getSurface(level, layer).m_data.size(), 
				(void*)&img.getSurface(level, layer).m_data[0]);
		}
	}

	// Add the GL job to create the texture
	m_tex.create(cmdb, init);

	// Add cleanup job
	cmdb.pushBackUserCommand(deleteImageCallback, imgPtr);

	// Finaly enque the GL job chain
	cmdb.flush();

	m_size = UVec3(init.m_width, init.m_height, init.m_depth);
}
Ejemplo n.º 3
0
//==============================================================================
void Ssao::initInternal(const ConfigSet& config)
{
	m_enabled = config.get("pps.ssao.enabled");

	if(!m_enabled)
	{
		return;
	}

	m_blurringIterationsCount = 
		config.get("pps.ssao.blurringIterationsCount");

	//
	// Init the widths/heights
	//
	const F32 quality = config.get("pps.ssao.renderingQuality");

	m_width = quality * (F32)m_r->getWidth();
	alignRoundUp(16, m_width);
	m_height = quality * (F32)m_r->getHeight();
	alignRoundUp(16, m_height);

	//
	// create FBOs
	//
	createFb(m_hblurFb, m_hblurRt);
	createFb(m_vblurFb, m_vblurRt);

	//
	// noise texture
	//
	GlCommandBufferHandle cmdb;
	cmdb.create(&getGlDevice());

	GlClientBufferHandle noise;
	noise.create(
		cmdb, sizeof(Vec3) * NOISE_TEX_SIZE * NOISE_TEX_SIZE, nullptr);

	genNoise((Vec3*)noise.getBaseAddress(), 
		(Vec3*)((U8*)noise.getBaseAddress() + noise.getSize()));

	GlTextureHandle::Initializer tinit;

	tinit.m_width = tinit.m_height = NOISE_TEX_SIZE;
	tinit.m_target = GL_TEXTURE_2D;
	tinit.m_internalFormat = GL_RGB32F;
	tinit.m_format = GL_RGB;
	tinit.m_type = GL_FLOAT;
	tinit.m_filterType = GlTextureHandle::Filter::NEAREST;
	tinit.m_repeat = true;
	tinit.m_mipmapsCount = 1;
	tinit.m_data[0][0] = noise;

	m_noiseTex.create(cmdb, tinit);

	//
	// Kernel
	//
	String kernelStr(getAllocator());
	Array<Vec3, KERNEL_SIZE> kernel;

	genKernel(kernel.begin(), kernel.end());
	kernelStr = "vec3[](";
	for(U i = 0; i < kernel.size(); i++)
	{
		String tmp(getAllocator());

		tmp.sprintf("vec3(%f, %f, %f) %s",
			kernel[i].x(), kernel[i].y(), kernel[i].z(),
			(i != kernel.size() - 1) ? ", " : ")");

		kernelStr += tmp;
	}

	//
	// Shaders
	//
	m_uniformsBuff.create(cmdb, GL_SHADER_STORAGE_BUFFER, 
		sizeof(ShaderCommonUniforms), GL_DYNAMIC_STORAGE_BIT);

	String pps(getAllocator());

	// main pass prog
	pps.sprintf(
		"#define NOISE_MAP_SIZE %u\n"
		"#define WIDTH %u\n"
		"#define HEIGHT %u\n"
		"#define KERNEL_SIZE %u\n"
		"#define KERNEL_ARRAY %s\n",
		NOISE_TEX_SIZE, m_width, m_height, KERNEL_SIZE, &kernelStr[0]);

	m_ssaoFrag.loadToCache(&getResourceManager(),
		"shaders/PpsSsao.frag.glsl", pps.toCString(), "r_");


	m_ssaoPpline = m_r->createDrawQuadProgramPipeline(
		m_ssaoFrag->getGlProgram());

	// blurring progs
	const char* SHADER_FILENAME = 
		"shaders/VariableSamplingBlurGeneric.frag.glsl";

	pps.sprintf(
		"#define HPASS\n"
		"#define COL_R\n"
		"#define IMG_DIMENSION %u\n"
		"#define SAMPLES 7\n", 
		m_height);

	m_hblurFrag.loadToCache(&getResourceManager(),
		SHADER_FILENAME, pps.toCString(), "r_");

	m_hblurPpline = m_r->createDrawQuadProgramPipeline(
		m_hblurFrag->getGlProgram());

	pps.sprintf(
		"#define VPASS\n"
		"#define COL_R\n"
		"#define IMG_DIMENSION %u\n"
		"#define SAMPLES 7\n", 
		m_width);

	m_vblurFrag.loadToCache(&getResourceManager(),
		SHADER_FILENAME, pps.toCString(), "r_");

	m_vblurPpline = m_r->createDrawQuadProgramPipeline(
		m_vblurFrag->getGlProgram());

	cmdb.flush();
}