Jump to content

Encoding text within the final image


photo

Recommended Posts

Hi,

We need to encode some ASCII text into the first lines of the real time generated images. The text could be for example encoded by setting the first line of pixels to a succession of black and white pixels, matching the binary of the text. The text is relatively short, between 100 and 500 ASCII-7bits characters, and changes every frame at 60Hz.

Multiple questions here:

  • What would be the best / easiest way to add such an encoded text as pixels into the first lines of the image?
  • What would you suggest for the encoding? Any experience? The image will be transmitted through a video transmitter, so some 4-2-2 compression may occur. No need for any encryption.

Thanks!

Link to comment

Hi Stephane,

I guess you can simply use visualizer (renderPoint2D) for that and draw some black and white pixels on top of the image (is that what you needed)? In that case, however, you can't get a precise control on the point size).

Alternative solution would be to encode this text line into the image / texture and apply on top via WidgetSprite. I guess that would be a preferable way of doing it.

Thanks!

 

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

Link to comment

I couldn't find a sample using widgetsprite, and moreover it must not be affected by any post render, so not usure how to go there. Mayeb a a quick code sample would bootstrap me here.

Alternatively, I tried with Ffp (as Visualizer can't be used because we already use it for a lot of debug info), but even something as simple as drawing a colored quad fails on me:

	Ffp::enable(Ffp::MODE_SOLID);
	Ffp::setOrtho(App::getWidth(), App::getHeight());
	Ffp::beginTriangles();
	Ffp::addTriangleQuads(1);
	Ffp::addVertex(0, 0); Ffp::setColor(1, 0, 0, 1);  //< crash here on setColor
	Ffp::addVertex(100, 0); Ffp::setColor(0, 1, 0, 1);
	Ffp::addVertex(100, 100); Ffp::setColor(1, 1, 1, 1);
	Ffp::addVertex(0, 100); Ffp::setColor(0, 1, 0, 1);
	Ffp::endTriangles();

What am I doing wrong (the code sample is taken directly from the doc by the way!)

Link to comment

WidgetSprite is not affected by any post processing effects, so you can safely use it. There are some samples available in UnigineScript section: https://developer.unigine.com/en/docs/2.16/api/library/gui/class.widgetsprite?rlang=cpp#see (they can be easily ported to the C++ I guess since the APIs are quite similar).

Dedicated FFp sample is available for C++ in SDK Browser -> Samples -> C++API -> Systems -> Ffp.

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

Link to comment

WidgetSprite:

  • The sample sprite_02 uses "core/gui/gui_white.png"; there is no such texture here. What is the fullpath() function?
  • Is it efficient to draw 500 widgetsprite per frame (each would be about 1 or 2 pixels only)?
  • Do you have a sample where I see how to create and edit every pixel of a runtime texture in C++?

Ffp:

  • The sample does not work. First, a line is missing causing a crash:
// In FfpPlugin
const char* get_name() override { return "FfpPlugin"; } //< missing line causes a crash
  • Second, even with this line fixed, nothing is drawn on screen. I'm obviously missing something crucial here but what? (attached AppSystemLogic.cpp in which I simply copied the Ffp sample)AppSystemLogic.cpp

Thanks!

Link to comment
Quote

The sample sprite_02 uses "core/gui/gui_white.png"; there is no such texture here. What is the fullpath() function?

What do you mean there is no such texture? It's located in <SDK>/data/core/gui directory:

image.png

fullpath() function is just alias for engine.filesystem.resolvePartialVirtualPath(path). You can check implementation in <SDK>/data/samples/samples.h

Quote
  • Is it efficient to draw 500 widgetsprite per frame (each would be about 1 or 2 pixels only)?
  • Do you have a sample where I see how to create and edit every pixel of a runtime texture in C++?

My initial idea was not about single texture for each pixel, but rather you fill the image with colors and draw this single image at once as a single sprite. You can call setImage() and pass pointer to the image in memory and you don't need to create an actual files on disk or whatsoever. Inside image you can set pixels colors to what you really need via set() method.

 

Quote
  • The sample does not work. First, a line is missing causing a crash:

That's quite strange. Which SDK version are you currently using? Just tried in 2.15.1 / 2.16 / 2.16.0.1 - sample building and running inside Visual Studio works as expected.

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

Link to comment

And regarding your AppSystemLogic, try to use it without plugin at all. Something like this:

void render()
{
	RenderTargetPtr render_target = Renderer::getRenderTarget();
	TexturePtr texture = Renderer::getTextureColor();

	RenderState::saveState();
	RenderState::clearStates();
	render_target->bindColorTexture(0, texture);
	render_target->enable();

	float time = Time::getSeconds();

	// screen size
	int width = App::getWidth();
	int height = App::getHeight();
	float radius = height / 2.0f;

	Ffp::enable(Ffp::MODE_SOLID);
	Ffp::setOrtho(width, height);

	// begin triangles
	Ffp::beginTriangles();

	// vertex colors
	const unsigned int colors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };

	// create vertices
	int num_vertex = 16;
	for (int i = 0; i < num_vertex; i++)
	{
		float angle = Math::Consts::PI2 * i / (num_vertex - 1) - time;
		float x = width / 2 + sinf(angle) * radius;
		float y = height / 2 + cosf(angle) * radius;
		Ffp::addVertex(x, y);
		Ffp::setColor(colors[i % 3]);
	}

	// create indices
	for (int i = 1; i < num_vertex; i++)
	{
		Ffp::addIndex(0);
		Ffp::addIndex(i);
		Ffp::addIndex(i - 1);
	}

	// end triangles
	Ffp::endTriangles(); // we are getting there, but nothing is visible on screen

	Ffp::disable();

	render_target->disable();
	render_target->unbindColorTextures();
	RenderState::restoreState();
}

int AppSystemLogic::init()
{
	Render::addCallback(Render::CALLBACK_END_VISUALIZER, MakeCallback(render));
	return 1;
}

 

  • Like 1

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

Link to comment
1 hour ago, silent said:

What do you mean there is no such texture? It's located in <SDK>/data/core/gui directory:

Indeed, the gui_white.png is in the sdk directory. But not in a newly created 2.15.1 project, nor in core.ung: (at least it's not visible in the asset browser) (nothing is filtered here)

image.png.e1e38fe3399119c105e7a2ca0ff9825b.png

 

1 hour ago, silent said:

Inside image you can set pixels colors to what you really need via set() method.

Got it! Tried this and it works fine!

Now, to update the drawn colors, should I create a new Image every frame and call sprite->setImage() with the new image, or can I simply use a once-created image and just update it? (I tried spriteImage(image, true) but it doesn't refresh when I update the image, or did I miss something here?).

 

1 hour ago, silent said:

That's quite strange. Which SDK version are you currently using? Just tried in 2.15.1 / 2.16 / 2.16.0.1 - sample building and running inside Visual Studio works as expected.

Stock 2.15.1. I did not rebuild the sample itself, but copy-pasted the relevant part in a newly created project. The crash is because get_name() is called on the plugin while it's not set.

 

39 minutes ago, silent said:

And regarding your AppSystemLogic, try to use it without plugin at all. Something like this:

That works, thanks!

 

One more question: apart from doing obvious perf measurement, would you rather recommend the FFP way or the sprite way?

Thanks!

Link to comment
Quote

One more question: apart from doing obvious perf measurement, would you rather recommend the FFP way or the sprite way?

I don't think that these kind of operations are capable to somehow significantly affect the final application framerate. The image size is quite small and copying texture (even each frame) should not give any bottlenecks. The only dangerous part here is memory management, you need to delete image when it's not needed anymore.

 

Quote

Indeed, the gui_white.png is in the sdk directory. But not in a newly created 2.15.1 project, nor in core.ung: (at least it's not visible in the asset browser) (nothing is filtered here)

Well, I have the same behavior I have also in 2.16+. Need to understand if that's intended or not.

 

Quote

Now, to update the drawn colors, should I create a new Image every frame and call sprite->setImage() with the new image, or can I simply use a once-created image and just update it? (I tried spriteImage(image, true) but it doesn't refresh when I update the image, or did I miss something here?).

In theory dynamic flag is created exactly for this purpose (at least to my understanding), I can give you more information tomorrow regarding this behavior.

 

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

Link to comment

So I got some answers regarding WidgetSprite and files display in Asset Browser.

1) Files in Asset Browser are only displayed when they have .meta. For some reason not all the core assets comes with .meta, so they are being skipped. Maybe we will generate meta for them in the next versions.

2) You need to call setImage each frame manually if you updated your source image. dynamic flag for setImage in WidgetSprite will help to reduce the CPU->GPU image upload, but noticeable difference you can see when your image is quite big (more than 1000 pixels). For small images there more likely will be no difference in speed.

{
	UNIGINE_PROFILER_SCOPED("dynamic0"); // slow
	w->setImage(image, 0);
}
{
	UNIGINE_PROFILER_SCOPED("dynamic1"); // fast
	w2->setImage(image, 1);
}

image.png

  • Thanks 1

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

Link to comment
×
×
  • Create New...