PixelBuffer GL3GraphicContextProvider::get_pixeldata(const Rect& rect, TextureFormat texture_format, bool clamp) const
	{
		TextureFormat_GL tf = OpenGL::get_textureformat(texture_format);
		if (!tf.valid)
			throw Exception("Unsupported texture format passed to GraphicContext::get_pixeldata");

		PixelBuffer pbuf(rect.get_width(), rect.get_height(), texture_format);
		OpenGL::set_active(this);
		if (!framebuffer_bound)
		{
			render_window->is_double_buffered() ? glReadBuffer(GL_BACK) : glReadBuffer(GL_FRONT);
		}
		if (glClampColor)
			glClampColor(GL_CLAMP_READ_COLOR, clamp ? GL_TRUE : GL_FALSE);

		Size display_size = get_display_window_size();

		glPixelStorei(GL_PACK_ALIGNMENT, 1);
		glPixelStorei(GL_PACK_ROW_LENGTH, pbuf.get_pitch() / pbuf.get_bytes_per_pixel());
		glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
		glPixelStorei(GL_PACK_SKIP_ROWS, 0);
		glReadPixels(rect.left, display_size.height - rect.bottom, rect.get_width(), rect.get_height(), tf.pixel_format, tf.pixel_datatype, pbuf.get_data());
		pbuf.flip_vertical();
		return pbuf;
	}
	PixelBuffer GL1GraphicContextProvider::get_pixeldata(const Rect& rect, TextureFormat texture_format, bool clamp) const
	{
		GLenum format;
		GLenum type;
		bool found = GL1TextureProvider::to_opengl_pixelformat(texture_format, format, type);
		if (!found)
			throw Exception("Unsupported pixel format passed to GraphicContext::get_pixeldata");

		PixelBuffer pbuf(rect.get_width(), rect.get_height(), texture_format);
		set_active();
		if (!framebuffer_bound)
			render_window->is_double_buffered() ? glReadBuffer(GL_BACK) : glReadBuffer(GL_FRONT);

		Size display_size = get_display_window_size();

		glPixelStorei(GL_PACK_ALIGNMENT, 1);
#ifndef __ANDROID__
		glPixelStorei(GL_PACK_ROW_LENGTH, pbuf.get_pitch() / pbuf.get_bytes_per_pixel());
		glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
		glPixelStorei(GL_PACK_SKIP_ROWS, 0);
#endif
		glReadPixels(rect.left, display_size.height - rect.bottom, rect.get_width(), rect.get_height(), format, type, pbuf.get_data());
		pbuf.flip_vertical();
		return pbuf;
	}
void D3DGraphicContextProvider::end_resize_swap_chain()
{
	Size viewport_size = get_display_window_size();
	viewports[0].Width = viewport_size.width;
	viewports[0].Height = viewport_size.height;
	viewports[0].TopLeftX = 0;
	viewports[0].TopLeftY = 0;
	window->get_device_context()->RSSetViewports(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, viewports);

	set_default_dsv();
}
void D3DGraphicContextProvider::set_default_dsv()
{
	if (default_depth != 0 && !default_depth_render_buffer)
	{
		TextureFormat texture_format = tf_depth_component32;
		if (default_depth <= 16)
			texture_format = tf_depth_component32;
		else  if (default_depth <= 24)
			texture_format = tf_depth_component24;

		Size viewport_size = get_display_window_size();

		default_depth_render_buffer = std::shared_ptr<D3DRenderBufferProvider>( new D3DRenderBufferProvider(window->get_device()));
		default_depth_render_buffer->create(viewport_size.width, viewport_size.height, texture_format, 1);
		default_dsv = default_depth_render_buffer->create_dsv(window->get_device());
	}

	ID3D11RenderTargetView *targets[] = { window->get_back_buffer_rtv() };
	ID3D11DepthStencilView *default_depth_stencil_rtv = (default_depth != 0) ? default_dsv.get() : nullptr;
	window->get_device_context()->OMSetRenderTargets(1, targets, default_depth_stencil_rtv);
}
D3DGraphicContextProvider::D3DGraphicContextProvider(D3DDisplayWindowProvider *window, const DisplayWindowDescription &display_desc)
:	window(window),
	current_prim_array_provider(0),
	current_program_provider(0),
	input_layout_set(false)
{
//	set_blend_color(Colorf::black);
//	set_blend_function(blend_one, blend_zero, blend_one, blend_zero);
//	enable_blending(false);

	default_depth = display_desc.get_depth_size();

	Size viewport_size = get_display_window_size();
	for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
	{
		viewports[i].Width = viewport_size.width;
		viewports[i].Height = viewport_size.height;
		viewports[i].TopLeftX = 0;
		viewports[i].TopLeftY = 0;
		viewports[i].MinDepth = 0.0f;
		viewports[i].MaxDepth = 1.0f;
	}
	window->get_device_context()->RSSetViewports(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, viewports);

	for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
	{
		scissor_rects[i].left = 0;
		scissor_rects[i].top = 0;
		scissor_rects[i].right = 0;
		scissor_rects[i].bottom = 0;
	}

	for (int i = 0; i < shadertype_num_types; i++)
		shader_bound[i] = false;

	set_default_dsv();

	SharedGCData::add_provider(this);
}