How-To: Save a HOOPS scene to an image format with a transparent background

HOOPS Visualize does not current support this workflow out of the box.

It is supported indirectly but not for specific image formats like PNG, JPEG, etc.

Instructions

3DF

The following outlines the process for Visualize 3DF;

  1. Create an Offscreen Rendering of the scene with a transparent background
  2. For a transparent background make sure the Insert_Image format is RGBA
  3. Obtain the raw image data using Show_Image
  4. Export the data to a file in the format of your choosing (e.g. PNG) using a 3rd party solution like stb_image_write.h.

Sample Code

The following code can be added to CSolidHoopsView.cpp in the hoopspartviewer project. It illustrates steps 1-3 above. In addition, it includes the resulting image under the model.

void CSolidHoopsView::OnExtraSlot2()
{
	static const size_t imageBytesPerPixel = 4;

	HC_KEY imageKey;
	char buffer[4096];
	HC_KEY image_seg = HC_Open_Segment("/image");
	{
		imageKey = HC_Insert_Image(0.0, 0.0, 0.0, "RGBA, name = transparent_background_image", 300, 300, 0);
	}
	HC_Close_Segment();

	const char* offscreenRenderSeg = "?driver/dx11/image";
	HC_Open_Segment(offscreenRenderSeg);
	{
		// for a completely transparent window background
		HC_Set_Driver_Options("window opacity = 0.0");

		HC_Insert_Line(-1.0, -1.0, 0.0, 1.0, 1.0, 0.0);

		// Using the image key modifier when setting the window id to indicate that we are rendering offscreen.
		sprintf(buffer, "isolated, use window id = image key = 0x%p, subscreen = (-1, 1, -1, 1)", (void*)imageKey);
		HC_Set_Driver_Options(buffer);
		HC_Set_Color("lines=blue , windows=green");
	}
	HC_Close_Segment();
	HC_Update_One_Display(offscreenRenderSeg);

	int width, height;
	char format[4096];
	float cx, cy, cz;
	HC_Show_Image_Size(imageKey, &cx, &cy, &cz, format, &width, &height);
	size_t pixelCount = width * height;
	size_t imageDataSize = imageBytesPerPixel * pixelCount;
	unsigned char* imageData = new unsigned char[imageDataSize];
	HC_Show_Image(imageKey, &cx, &cy, &cz, format, &width, &height, imageData);
	unsigned char* current = imageData;

	// Analyze resulting image.
	static bool analizeImage = true;
	if (analizeImage)
	{
		bool foundTransparent = false;
		for (size_t i = 0; i < pixelCount && !foundTransparent; ++i)
		{
			if (current[3] < 255)
				foundTransparent = true;
			current += imageBytesPerPixel;
		}
	}
	delete[] imageData;

	HC_Delete_Segment(offscreenRenderSeg);

	HC_Open_Segment_By_Key(m_pHView->GetModelKey());
	{
		HC_Include_Segment_By_Key(image_seg);
		HC_Set_Color("windows=red");
	}
	HC_Close_Segment();

	m_pHView->Update();
}

Showing Transparency

Adding a sphere to the scene created above and orbiting the camera shows that the image has a transparent background. The sphere can be see through the image in the video below;

HPS

The approach is very similar for HPS Offscreen Rendering.

The hardcopy image export is an option but does not support a transparent window background.