void gfx::BloomProgram::Render(){
	//Do brightpass
	ShaderProgram* prog = g_ShaderBank.GetProgramFromHandle(m_BrightPassShader);
	prog->Apply();
	const int WORK_GROUP_SIZE = 32;
	GLuint WorkGroupSizeX = GLuint((m_Width + WORK_GROUP_SIZE - 1) / float(WORK_GROUP_SIZE));
	GLuint WorkGroupSizeY = GLuint((m_Height + WORK_GROUP_SIZE - 1) / float(WORK_GROUP_SIZE));
	prog->SetUniformTextureHandle("g_Image", m_TargetTex, 1);
	prog->SetUniformVec2("g_ScreenSize", glm::vec2(m_Width, m_Height));
	prog->SetUniformFloat("g_Threshold", 0.4f);
	prog->SetUniformFloat("g_Smoothness", 0.8f);
	glBindImageTexture(0, m_BloomTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
	glDispatchCompute(WorkGroupSizeX, WorkGroupSizeY, 1);
	//blur result
	m_BlurProgram->Render();
	//add to final target
	prog = g_ShaderBank.GetProgramFromHandle(m_BloomShader);
	prog->Apply();
	prog->SetUniformTextureHandle("g_BluredBloomTex", m_BlurProgram->GetBluredTexture(), 1);
	prog->SetUniformTextureHandle("g_ColorBuffer", m_TargetTex, 2);
	prog->SetUniformVec2("g_ScreenSize", glm::vec2(m_Width, m_Height));
	glBindImageTexture(0, m_BloomTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
	glDispatchCompute(WorkGroupSizeX, WorkGroupSizeY, 1);

}
void TerrainDeformationProgram::Initialize(){
	m_FrameBuffer = new FrameBuffer();
	m_FrameBuffer->Init();

	glGenTextures(1, &m_BrushTexture);
	glBindTexture(GL_TEXTURE_2D, m_BrushTexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_BRUSH_RES, m_BRUSH_RES, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glBindTexture(GL_TEXTURE_2D, 0);
	//fill in brush
	m_BrushGenProgram = g_ShaderBank.LoadShaderProgram("../../../shader/BrushTexGenProgram.glsl");
	ShaderProgram* prog = g_ShaderBank.GetProgramFromHandle(m_BrushGenProgram);
	prog->Apply();
	prog->SetUniformFloat("hardness", 1.0f);
	glBindImageTexture(0, m_BrushTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
	const int WORK_GROUP_SIZE = 32;
	GLuint WorkGroupSize = GLuint((m_BRUSH_RES + WORK_GROUP_SIZE - 1) / float(WORK_GROUP_SIZE));
	glDispatchCompute(WorkGroupSize, WorkGroupSize, 1);
	
	m_DrawProgram = g_ShaderBank.LoadShaderProgram("../../../shader/SpriteShader.glsl");
	m_BrushTex = new Texture();
	m_BrushTex->Init("../../../binasset/texture/brush.png", TEXTURE_COLOR);

	m_FilterProgram = g_ShaderBank.LoadShaderProgram("../../../shader/TerrainDeformFilter.glsl");
}
void gfx::LineRenderProgram::Draw()
{
	glDisable( GL_DEPTH_TEST );
	glLineWidth(4.0f);
	glEnable(GL_BLEND);
	ShaderProgram* prog = g_ShaderBank.GetProgramFromHandle(m_ProgramHandle);
	prog->Apply();
	glm::mat4 vp = m_RenderJobManager->GetProj() * m_RenderJobManager->GetView();
	prog->SetUniformMat4("vp", vp);
	
	rVector<Line>& lines = m_RenderJobManager->GetLines();
	for(int i = 0; i < lines.size(); i++)
	{
		prog->SetUniformVec4("Color", lines[i].Color);
		prog->SetUniformVec3("pos1", lines[i].Origin);
		prog->SetUniformVec3("pos2", lines[i].Destination);
		prog->SetUniformFloat("animation", lines[i].AnimationProgres);
		if(lines[i].Dashed)
		{
			prog->SetUniformTextureHandle("Tex", m_DashedTexture, 0);
		}
		else
		{
			prog->SetUniformTextureHandle("Tex", m_Texture, 0);
		}
		glBindVertexArray( 0 );
		glDrawArrays(GL_POINTS, 0, 1);
	}
	glUseProgram( 0 );
	glEnable( GL_DEPTH_TEST );
	glLineWidth(1.0f);
	glDisable(GL_BLEND);
}