Jump to content

I have a BGRA32 buffer, what is the best way to get that on to a surface?


photo

Recommended Posts

Hi Angus,

We are not working with BGRA textures (we use RGBA), so the conversion is required. For the fast GPU transfers I guess you can try to use native DirectX / OpenGL code or use CUDA in order to transfer textures faster (upload / download).

Is there a particular use-case for this - could you please give us more details?

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Hi Silent,

 

Thanks for the quick reply. The use-case is that I'm using the Chromium Embedded Framework (CEF) off-screen renderer (OSR) to render a web-page with a transparent background. The idea is that I'll be able to use web-tech to do both WidgetSprite 2D overlays and Material (diffuse) texture setting to display web content on 3D surfaces

 

The system works by passing a class in to the CEF which then gets a call-back when ever the off-screen rendered page is updated, up to 30FPS. The callback looks like this

void OSRHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height) {

	unsigned char* image_data_from_chrome = (unsigned char*)buffer;


	static Unigine::ImagePtr page_image = Unigine::Image::create();
	
	static bool created = false;

	if (created == false) {
		page_image->create2D(width, height, Unigine::Image::FORMAT_RGBA32F, 1, 1, 1);
		created = true;
	}

	static Unigine::BlobPtr blob = Unigine::Blob::create(page_image->getSize());

	blob->setData(image_data_from_chrome, width * height * 4);
	mutex.lock();
	page_image->setPixels(blob);
	mutex.unlock();

	return;


}

 

So in the "image_data_from_chrome" I have a pointer to a BGRA image of the web page that I've loaded. What I'd like to know is how best to set that image data on to a 2D WidgetSprite and on to a material's colour texture. I'll look up elsewhere about how to convert BGRA to RGBA but the bit I'm unsure about is how best to set the pixels on the objects.

 

Cheers.

Link to comment

Hi,

Obviously you have 2 options, convert on cpu or convert on gpu.

Converning on cpu can be too slow for 30fps, but it depends on your image resolution, you can test it first (There is also an option to distribute this on multiple threads), converting code is trivial:

float *data = (float*)page_image->getPixels();
int size = width * height * 4;
for (int i = 0; i < size; i += 4)
{
	std::swap(data[i], data[i + 2]);
}

Or you can do that on gpu.

You don't need an Image instance in this case, you need to write your fragment shader, custom material and create a texture and a texturerender. For example please look at c++ TextureRender sample how to render to texture with custom shader. I assume vertex shader will be something like this:

#include <core/shaders/common/fragment.h>

INIT_TEXTURE(0, TEX)

MAIN_BEGIN(FRAGMENT_OUT, FRAGMENT_IN)
	OUT_COLOR = TEXTURE_FETCH(TEX, IN_POSITION.xy).bgra;
MAIN_END

Alternatively, you can use our compute shaders or cuda / opencl frameworks for this.

Link to comment
×
×
  • Create New...