bool Context::_hbao_init()

in roboschool/cpp-household/render-ssao.cpp [90:162]


bool Context::_hbao_init()
{
	program_depth_linearize = load_program("fullscreen_triangle.vert.glsl", "", "ssao_depthlinearize.frag.glsl", 0, 0, "#version 410\n");
	if (!program_depth_linearize->log().isEmpty()) {
		fprintf(stderr, "Roboschool built-in render compiled with shadows, but SSAO shaders didn't load (1)\n");
		return false;
	}
	program_depth_linearize->link(); // always returns true :(
	location_clipInfo = program_depth_linearize->uniformLocation("clipInfo");

	program_hbao_calc = load_program("fullscreen_triangle.vert.glsl", "", "ssao_hbao.frag.glsl", 0, 0, "#version 410\n#define AO_DEINTERLEAVED 0\n#define AO_BLUR 0\n#define AO_LAYERED 0\n");
	if (!program_hbao_calc->log().isEmpty()) {
		fprintf(stderr, "Roboschool built-in render compiled with shadows, but SSAO shaders didn't load (2)\n");
		return false;
	}
	program_hbao_calc->link();
	location_RadiusToScreen = program_hbao_calc->uniformLocation("RadiusToScreen");
	location_R2 = program_hbao_calc->uniformLocation("R2");
	location_NegInvR2 = program_hbao_calc->uniformLocation("NegInvR2");
	location_NDotVBias = program_hbao_calc->uniformLocation("NDotVBias");
	location_InvFullResolution = program_hbao_calc->uniformLocation("InvFullResolution");
	location_InvQuarterResolution = program_hbao_calc->uniformLocation("InvQuarterResolution");
	location_AOMultiplier = program_hbao_calc->uniformLocation("AOMultiplier");
	location_PowExponent = program_hbao_calc->uniformLocation("PowExponent");
	location_projInfo = program_hbao_calc->uniformLocation("projInfo");
	location_projScale = program_hbao_calc->uniformLocation("projScale");
	location_projOrtho = program_hbao_calc->uniformLocation("projOrtho");
	location_float2Offsets = program_hbao_calc->uniformLocation("float2Offsets");
	location_jitters = program_hbao_calc->uniformLocation("jitters");

	location_texLinearDepth = program_hbao_calc->uniformLocation("texLinearDepth");
	location_texRandom = program_hbao_calc->uniformLocation("texRandom");

	useful.reset(new UsefulStuff);

	float numDir = 8; // keep in sync to glsl
	signed short hbaoRandomShort[HBAO_RANDOM_ELEMENTS*MAX_SAMPLES*4];
	for(int i=0; i<HBAO_RANDOM_ELEMENTS*MAX_SAMPLES; i++) {
		float r1 = static_cast<float>(rand()) / static_cast <float>(RAND_MAX);;
		float r2 = static_cast<float>(rand()) / static_cast <float>(RAND_MAX);;
		// Use random rotation angles in [0,2PI/NUM_DIRECTIONS)
		float angle = 2.f * nv_pi * r1 / numDir;
		useful->hbaoRandom[i].x = cosf(angle);
		useful->hbaoRandom[i].y = sinf(angle);
		useful->hbaoRandom[i].z = r2;
		useful->hbaoRandom[i].w = 0;
#define SCALE ((1<<15))
		hbaoRandomShort[i*4+0] = (signed short)(SCALE*useful->hbaoRandom[i].x);
		hbaoRandomShort[i*4+1] = (signed short)(SCALE*useful->hbaoRandom[i].y);
		hbaoRandomShort[i*4+2] = (signed short)(SCALE*useful->hbaoRandom[i].z);
		hbaoRandomShort[i*4+3] = (signed short)(SCALE*useful->hbaoRandom[i].w);
#undef SCALE
	}

	hbao_random.reset(new Texture());
	glBindTexture(GL_TEXTURE_2D_ARRAY, hbao_random->handle);
	glTexStorage3D (GL_TEXTURE_2D_ARRAY,1,GL_RGBA16_SNORM,HBAO_RANDOM_SIZE,HBAO_RANDOM_SIZE,MAX_SAMPLES);
	glTexSubImage3D(GL_TEXTURE_2D_ARRAY,0,0,0,0, HBAO_RANDOM_SIZE,HBAO_RANDOM_SIZE,MAX_SAMPLES,GL_RGBA,GL_SHORT,hbaoRandomShort);
	glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
	glBindTexture(GL_TEXTURE_2D_ARRAY,0);

	for (int i=0; i<MAX_SAMPLES; i++) {
		hbao_randomview[i].reset(new Texture());
		glTextureView(hbao_randomview[i]->handle, GL_TEXTURE_2D, hbao_random->handle, GL_RGBA16_SNORM, 0, 1, i, 1);
		glBindTexture(GL_TEXTURE_2D, hbao_randomview[i]->handle);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	return true;
}