draw_quad and bmap_rendertarget issue

Posted By: Kartoffel

draw_quad and bmap_rendertarget issue - 12/12/15 13:11

Just ran into this problem, pretty sure it's related to this one, posted by txesmi:

when rendering into a bmap using bmap_rendertarget and draw_quad the quad does not get drawn if it's outside of the window's dimensions.

what I mean by this is that draw_quad can draw on sections of a rendertarget that are outside of the screen's resolution - but only if some part of the quad is inside the rendertarget's dimensions.

Looks like there's some culling going on that uses the dimensions of the engine window instead of the rendertarget's dimensions.

Here's an example to test:
Code:
#include <acknex.h>

void main()
{
	fps_max = 60;
	
	wait(1);
	
	video_set(256, 256, 0, 2);
	
	wait(1);
	
	//
	
	BMAP * RenderTarget = bmap_createblack(512, 512, 8888); // create 512x512 bmap used as rendertarget -> bigger than the video resolution (256x256)
	bmap_fill(RenderTarget, vector(40, 32, 30), 100); // fill it with some dark color
	
	BMAP * SomeQuad = bmap_createblack(100, 75, 8888); // create a bmap to draw
	bmap_fill(SomeQuad, vector(255, 255, 255), 100); // fill with white, this one is colored using draw_quad()'s color-parameter
	
	//
	
	bmap_rendertarget(RenderTarget, 0, 1); // render folowing stuff into bmap, keep the bmap's content
	
	draw_quad(SomeQuad, vector(  0,   0, 0), NULL, NULL, NULL, vector(120, 240,  40), 100, 0); // GREEN: draw at position: 0, 0
	draw_quad(SomeQuad, vector(150,  50, 0), NULL, NULL, NULL, vector( 30, 300, 240), 100, 0); // RED:   draw at position: 300, 100 
	draw_quad(SomeQuad, vector(250, 250, 0), NULL, NULL, NULL, vector(240, 140,  40), 100, 0); // BLUE:  partially outside, can draw outside
	draw_quad(SomeQuad, vector(290, 325, 0), NULL, NULL, NULL, vector(240, 240, 240), 100, 0); // [ISSUE #1]: WHITE: fully outside, this one gets culled
	
	bmap_rendertarget(NULL, 0, 0); // stop rendering into bmap
	
	//
	
	// [ISSUE #2]: without this the BMAP*'s content is lost when changing the video resolution or minimizing the game when running acknex in fullscreen
	bmap_to_format(RenderTarget, bmap_format(RenderTarget)); // force bmap rewrite
	
	video_set(512, 512, 0, 2); // set video resolution to the rendertarget's size
	
	//
	
	PANEL * test_pan = pan_create("flags = SHOW;", 0); // create panel to show the rendertarget's content
	test_pan.bmap = RenderTarget;
}


It starts up with a resolution of 256x256 and creates a 512x512 BMAP*.
Then it renders 4 rectangles into this BMAP* using draw_quad, a green one, a red one, a blue one and a white one.
After this the resolution changes from 256x256 to 512x512 and the rendered image is being displayed using a panel.
In the screenshot I also marked a purple and a white area:



The purple area shows the application's initial dimensions.
The green and red rectangle which are fully inside the window are rendered correctly as expected.
The blue one which only intersects the window's resolution partially is also rendered completely.
However, the white one - which is not inside the window - is not being rendered at all, it should appear where the white area is marked in the screenshot.

The code example also addresses another issue (marked with '[ISSUE #2]' in the above code example):
after using bmap_rendertarget on a BMAP*, it will lose it's content when changing the video resolution or minimizing the game when running acknex in fullscreen.
You can test this by commenting out the line with bmap_to_format();
I suspect that the bmap somehow stays a rendertarget, but I'm not too sure about this.

I sincerely hope that at least the first issue (the one related to draw_quad) can be solved somwhere in the near future since this is a crucial feature I need for my current project.

kind regards, Alex
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 12/15/15 16:58

Some feedback on whether or not this has been acknowledged would be nice...
Posted By: jcl

Re: draw_quad and bmap_rendertarget issue - 12/16/15 11:01

Yes, it's the same reason as with draw_quad. While 3D drawing uses the defined target size, 2D drawing is restricted to the screen size.

For preserving the content of a rendertarget, copy it into a normal, non-target bitmap. The rendertarget behavior can be device dependent.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 12/16/15 14:06

Thanks for the answer, but does this mean that there's no way to fix this behaviour of draw_xxx functions and enable rendering into big rendertargets using draw_quad?
Like I've said, being able to do so is quite important for what I'm planning to do and it would make things very complicated in that case. frown

Edit: I'm sorry but shouldn't fixing this require just a really small change in the engine's code?
Posted By: jcl

Re: draw_quad and bmap_rendertarget issue - 12/21/15 11:49

The only way at the moment for drawing into extended render targets is using a 3D drawing function. I have 2D extended rendering on the planned features list, but it's not yet clear if it's possible in a simple way.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 12/21/15 16:18

Thanks again, I'd really appreciate it if this could make it into an upcoming update.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 12/29/15 10:07

I just ran into another problem using draw_quad and bmap_rendertarget.
It seems like draw_quad performs incorrect alphablending:



In this screenshot I'm drawing a title bar with a soft shadow onto an orange (100% opaque) bmap.
It should look like the top image but the bottom one is the result.

As you can see, the background (in this case a blue-green checker pattern) is clearly visible which means that draw_quad has lowered the alpha values of these pixels.

Sadly, this behaviour renders alphablending useless and causes me a lot of trouble.
Posted By: jcl

Re: draw_quad and bmap_rendertarget issue - 12/29/15 10:29

Panels and 2D elements are just written on the screen by standard blit operations. There is no "alphablending". Alpha and RGB just overwrite the alpha and RGB of the previous elements.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 12/29/15 11:02

Well, bmap_blit/_blitpart is a function that overwrites the bmap's pixels (I guess it uses something like memcpy to copy the pixel's color values).
draw_quad, however, seems to use some kind of blending. It has to, since it supports an 'alpha'-parameter as blending opacity and does produce correct results when rendering directly onto the screen.

In my example above, the rgb-channels are blended correctly but the alpha channel is not.

I'm not sure if draw_quad uses something similar to a shader, but I know that you get the same, incorrect blending when using the wrong values for DestBlend and SrcBlend in a shader's pass.

The problem is really just related to draw_quad in combination with bmap_rendertarget.
When using panels with different layers, this problem does not occur.
Neither does it when draw_quad is being used to draw an image directly onto the screen (without bmap_rendertarget).

Edit: Thinking about it, the reason why it works when rendering onto the screen is most likely because the screen's buffer doesn't use an alpha channel, so there's nothing to mess up.
...which means that bmap_rendertarget is probably not the culprit here, it's the blending-op that 2D-drawing-functions use.
Posted By: jcl

Re: draw_quad and bmap_rendertarget issue - 12/29/15 13:09

Yes. 2D operations just write content on the background. When the target has no alpha channel, as is the case for the screen, if can not become transparent by blitting content onto it. But if the target has an alpha channel, your operation writes into it and then the target becomes transparent at the same places where the blitted content was transparent. At least that's how I would interpret the problem you're describing.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 12/29/15 13:36

Exactly, but this makes it impossible to blit a bmap with transparency onto another bmap that is using transparency aswell - which is what I'm trying to do.

The only workaround I can come up with is using bmap_process. This way I could specify the blending mode in the shader's pass myself.
However, in that case the whole bmap needs to be processed for every single bmap that I want to blit which is a bit of an overkill for blitting a lot of small bmaps into a big one.

I could temporarily try to use this workaround but I hope that there'll be a way to alter how draw_-functions blend their content into the target-bmap, or simply chaging these functions to always use "correct" blending.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 01/05/16 14:05

Soo.. I hate to be pushy, sorry, but I'm really concerned about one of the issues I addressed - being able to use draw_quad() on big
rendertargets and I have the feeling that I'm just being ignored and nothing's going to move forward.

That draw_...()-functions are culled when they're outside of the window's size is obviously a problem that makes bmap_rendertarget()
kind of useless, since I can't guarantee that the final user has a screen resolution high enough to fit all my draw_() calls in it.
In my case of rendering onto big atlas-textures, most users will definitely not have big enough screens to fit the whole texture in it.

I can't really believe that fixing this is going to need a lot of modifications. The culling-area for draw_...()-functions simply needs to
be set to the bmap's dimensions when calling bmap_rendertarget(), and reset to the window's size when it's disabled again.

As a workaround I tried bmap_blit(part)... However, despite having a pretty beefy cpu, the time it takes to blit some bmaps just skyrockets
when using it. Drawing a medium number of quads takes roughly 1 millisecond using draw_quad - while bmap_blitpart needs more than 1000
milliseconds.

Knowing that Acknex's updates have become extremely rare, I'd just like to see that draw_quad will work the way it should be working
in the (hopefully near) future, since I'm relying quite a lot on it and I'm having trouble proceeding without it.


I don't really know what else to say than asking you to try solving this issue.

kind regards, Alex
Posted By: jcl

Re: draw_quad and bmap_rendertarget issue - 01/05/16 15:54

I understand, but if I were you, I would certainly not wait for the next Gamestudio update. I would just finish my project without draw_quad.

It's on my list, but I can not quickly produce an update for you. Draw_quad is the central panel drawing function and used at about 50 places in the code. Panels are early clipped at screen corners for speeding up 2D games. And there are internal functions that use draw_quad with a render target and also rely on screen clipping. Anything that affects existing projects in this way must be carefully implemented and tested, it's not done in half an hour.

I must also admit that the problem seemed not really urgent to me. Sure, you can not use draw_quad for your purpose, but there are tons of other draw functions. Can't you instead use draw_obj with a bmap object, or even just call a D3D draw primitive?
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 01/05/16 16:12

Okay, thanks for the reply.

It's just that every other approach I tried is just way too slow.
However, I'll see if I manage to get something using the directx api.
I'm not sure if this will work with acknex's bmap struct, though.
Posted By: Kartoffel

Re: draw_quad and bmap_rendertarget issue - 01/05/16 19:00

Well, now I look stupid.

Fixing this myself was actually possible and in the end it worked out much better than I thought.

I tried the draw primitive approach you've recommended. Took me quite a while to make that thing
render textures instead of vertex colors but I managed to get something usable.

For some reason it event works flawlessly with bmap_rendertarget(), which I did not expect at all.

Seems like I won't have to worry about this anymore, thanks again for the hint.
© 2024 lite-C Forums