View Issue Details

IDProjectCategoryView StatusLast Update
0003019FSSCPscriptingpublic2014-03-14 08:55
ReporterAxem Assigned Toniffiwan  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Summary0003019: Odd transparency when using Camera.Self
DescriptionDrawing things like gr.drawRectangle get really weird when I change to a new camera and use the Camera.Self handle. Suddenly a solid opaque rectangle becomes transparent (I suspect its rendering it with additive transparency).

See attached script. Press Enter while in game play to switch to a new camera that follows the player. The Red Box should always be opaque.
TagsNo tags attached.

Activities

Axem

2014-03-09 20:45

reporter  

testcamera-sct.tbm (600 bytes)

Axem

2014-03-10 02:30

reporter   ~0015644

Last edited: 2014-03-10 03:17

Fun thing to note while playing with this, throwing a gr.drawString just before the gr.drawRectangle won't cause the problem to manifest.

So it may not just be the .Self parameter but something in the camera code screwing up a drawing function?

m_m

2014-03-10 08:45

developer   ~0015645

Just tried this but I can't reproduce it with retail data. Which mod are you using?

Axem

2014-03-11 00:15

reporter   ~0015647

I was running with retail data as well. Could it be a video card issue somehow? I have a ATI 5870 and I got Spoon to run it with a GTX570. Same problem on both.

I also got SDM to test with his Intel HD 4000 and he doesn't get the problem.

niffiwan

2014-03-11 06:19

developer   ~0015648

I can't reproduce the bug either.

Nvidia GTS450
Retail data
r10474 Debug & r10275 release
Linux

niffiwan

2014-03-12 10:26

developer   ~0015650

Per IRC discussion with Axem today, I reran the tests ensuring that I had something behind the square. Both cases still seem opaque (see attached screenshots)

Maybe command line options have some effect? Here's mine for reference anyway:
-mod mantis_sandbox -missile_lighting -3dshockwave -post_process -soft_particles -fxaa -dualscanlines -targetinfo -ship_choice_3d -weapon_choice_3d -3dwarp -warp_flash -snd_preload -fps -window -nograb -fov 0.5 -ambient_factor 40 -spec_exp 11 -spec_point 0.6 -spec_static 0.8 -spec_tube 0.4 -ogl_spec 60 -res 1600x900

niffiwan

2014-03-13 01:49

developer   ~0015651

Last edited: 2014-03-13 01:57

From some more testing, it seems that the issue will be masked if you are displaying the FPS gauge, or the mem stats gauge.

In other words, you need to attempt to reproduce on a release (non-debug) build AND ensure -fps, -pos, -stats, -coords, -show_mem_usage (and maybe others) are all switched off.

Axem

2014-03-13 02:25

reporter   ~0015653

Last edited: 2014-03-13 02:30

After more playing around, this behavior does not occur with other drawing functions such as drawLine or drawCircle. drawRect seems to be the odd one out for some weird reason.

Edit: pic uploaded with drawRect not working right and drawCircle working

Axem

2014-03-13 02:30

reporter  

screen0437.jpg (132,826 bytes)   
screen0437.jpg (132,826 bytes)   

niffiwan

2014-03-13 07:48

developer   ~0015654

Last edited: 2014-03-13 11:37

From tracing through the state with a debugger, it seems that the problem is indeed additive blending being used incorrectly. This is the stack when the external camera is enabled.

(gdb) bt
#0 opengl_setup_render_states (r=@0x7fffffffd87c: 127, g=@0x7fffffffd880: 0, b=@0x7fffffffd884: 0, alpha=@0x7fffffffd874: 255, tmap_type=@0x7fffffffd878: 1, flags=280, is_scaler=0) at graphics/gropenglstate.cpp:1251
0000001 0x00000000004e172f in opengl_tmapper_internal (nv=4, verts=0x2d021b0, flags=280, is_scaler=0) at graphics/gropengldraw.cpp:1279
0000002 0x00000000004e1e9d in gr_opengl_tmapper (nverts=4, verts=0x2d021b0, flags=280) at graphics/gropengldraw.cpp:1443
0000003 0x00000000007d6e11 in g3_draw_poly_constant_sw (nv=4, pointlist=0x7fffffffda20, tmap_flags=280, constant_sw=0.100000001) at render/3ddraw.cpp:466
0000004 0x00000000007db130 in g3_draw_2d_rect (x=100, y=100, w=100, h=100, r=255, g=0, b=0, a=255) at render/3ddraw.cpp:1718
0000005 0x00000000004d0b95 in gr_rect (x=100, y=100, w=100, h=100, resize=false) at graphics/2d.cpp:1470
0000006 0x00000000008fd308 in l_Graphics_drawRectangle_f (L=0x2996b80) at parse/lua.cpp:13021
0000007 0x00007ffff648b23c in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
0000008 0x00007ffff6495d88 in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
0000009 0x00007ffff648b64d in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
0000010 0x00007ffff648a8d7 in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
#11 0x00007ffff648b802 in ?? () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
0000012 0x00007ffff6487361 in lua_pcall () from /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
0000013 0x00000000007476ae in script_state::RunBytecodeSub (this=0x146c5e0, in_lang=1, in_idx=2, format=0 '\000', data=0x0) at parse/scripting.cpp:865
0000014 0x0000000000747854 in script_state::RunBytecode (this=0x146c5e0, hd=..., format=0 '\000', data=0x0) at parse/scripting.cpp:906
0000015 0x00000000007467ff in ConditionedHook::Run (this=0x29e64d8, sys=0x146c5e0, action=3, format=0 '\000', data=0x0) at parse/scripting.cpp:510
0000016 0x00000000007478e4 in script_state::RunCondition (this=0x146c5e0, action=3, format=0 '\000', data=0x0, objp=0x0, more_data=0) at parse/scripting.cpp:917
0000017 0x00000000004d0cd8 in gr_flip () at graphics/2d.cpp:1510
0000018 0x00000000004142eb in game_flip_page_and_time_it () at freespace2/freespace.cpp:3888
0000019 0x0000000000415777 in game_frame (paused=false) at freespace2/freespace.cpp:4513
0000020 0x0000000000416023 in game_do_frame () at freespace2/freespace.cpp:4816
0000021 0x00000000004182d8 in game_do_state (state=2) at freespace2/freespace.cpp:6498
0000022 0x00000000004c06ff in gameseq_process_events () at gamesequence/gamesequence.cpp:409
0000023 0x0000000000419172 in game_main (cmdline=0x2231360 "") at freespace2/freespace.cpp:7065
0000024 0x0000000000419372 in main (argc=1, argv=0x7fffffffe288) at freespace2/freespace.cpp:7199
(gdb) print gr_screen.current_alphablend_mode
$12 = 1
(gdb) print gr_screen.current_alpha
$14 = 0.5

Note the state of gr_screen.current_alphablend_mode & gr_screen.current_alpha. This means that this code is executed at code/graphics/gropenglstate.cpp:1230 which causes the colour change. (see the current value of the 1st param passed to opengl_setup_render_states, r=@0x7fffffffd87c: 127)

        } else {
            tmap_type = TCACHE_TYPE_NORMAL;
            alpha_blend = ALPHA_BLEND_ADDITIVE; // ALPHA_BLEND_ALPHA_ADDITIVE;

            // Blend with screen pixel using src*alpha+dst
            float factor = gr_screen.current_alpha;

            alpha = 255;

            if (factor < 1.0f) {
                r = fl2i(r * gr_screen.current_alpha);
                g = fl2i(g * gr_screen.current_alpha);
                b = fl2i(b * gr_screen.current_alpha);
            }

So... next step is to hunt down what is setting this state in the external camera mode...

======================

Edit:

Seems that gr_screen.current_alphablend_mode & gr_screen.current_alpha are only changed in gr_set_bitmap(), which is... unfortunate. In other words anytime a bitmap is set (for rendering later) the alpha can left in a state which can mess up the next rectangle to be drawn (and all the LUA onFrame hooks are run near last in each frame).

Also, the reason why the alpha is OK when "inside the ship" is that the HUD (somehow, haven't traced it out yet) sets the alpha to 1 / off (somewhere inside game_render_hud(cid);)

And lastly, drawCircle is fine because it ultimately calls gr_opengl_arc(), which doesn't use alphablend_mode / current_alpha to alter the colours.

(speculation) maybe the solution is to create a new function for only drawing 2D rectangles without textures? The other option would be to mess with opengl_setup_render_states() and that seems a little more likely to have side effects. Unless someone can explain to me why "alpha_blend = ALPHA_BLEND_ADDITIVE;" is a good idea when you don't have a bitmap to draw to the rectangle

niffiwan

2014-03-13 12:36

developer   ~0015655

Last edited: 2014-03-13 12:37

Or... for a much simpler solution I could borrow an idea from Valathil and set a bitmap to "fix" the alpha settings :) It kinda makes sense (if I understand this correctly) as gr_rect is using the last-used-bitmaps' alpha info anyway.

This seems to fix the issue for me - Axem, could you also give it a test? (I'll try to create a build tomorrow morning)

https://github.com/niffiwan/fs2open.github.com/commit/a3c0bbe089db73f2af68e274d6742a8699dd0f80

commit a3c0bbe089db73f2af68e274d6742a8699dd0f80
Author: niffiwan
Date: Thu Mar 13 22:25:06 2014 +1000

    Fix mantis 3019: flush bitmap to prevent alpha-additive-blend shenanigans with lua drawRectangle

diff --git a/code/parse/lua.cpp b/code/parse/lua.cpp
index 3c1f637..6f22695 100644
--- a/code/parse/lua.cpp
+++ b/code/parse/lua.cpp
@@ -13018,6 +13018,7 @@ ADE_FUNC(drawRectangle, l_Graphics, "number X1, number Y1, number X2, number Y2,
 
        if(f)
        {
+ gr_set_bitmap(0); // gr_rect will use the last bitmaps info, so set to zero to flush any previous alpha state
                gr_rect(x1, y1, x2-x1, y2-y1, false);
        }
        else

Axem

2014-03-13 22:26

reporter   ~0015656

With a one line patch like that I just copy pasted it to my files and made a build. :p And the issue is FIXED!

niffiwan

2014-03-14 08:55

developer   ~0015659

Fix committed to trunk@10493.

Related Changesets

fs2open: trunk r10493

2014-03-14 03:57

niffiwan


Ported: N/A

Details Diff
Fix mantis 3019: flush bitmap to prevent alpha-additive-blend shenanigans with lua drawRectangle Affected Issues
0003019
mod - /trunk/fs2_open/code/parse/lua.cpp Diff File

Issue History

Date Modified Username Field Change
2014-03-09 20:45 Axem New Issue
2014-03-09 20:45 Axem File Added: testcamera-sct.tbm
2014-03-10 02:30 Axem Note Added: 0015644
2014-03-10 03:17 Axem Note Edited: 0015644
2014-03-10 08:45 m_m Note Added: 0015645
2014-03-11 00:15 Axem Note Added: 0015647
2014-03-11 06:19 niffiwan Note Added: 0015648
2014-03-12 10:24 niffiwan File Added: 3019-ext-cam.png
2014-03-12 10:24 niffiwan File Added: 3019-norm-cam.png
2014-03-12 10:26 niffiwan Note Added: 0015650
2014-03-13 01:49 niffiwan Note Added: 0015651
2014-03-13 01:57 niffiwan Note Edited: 0015651
2014-03-13 02:25 Axem Note Added: 0015653
2014-03-13 02:30 Axem File Added: screen0437.jpg
2014-03-13 02:30 Axem Note Edited: 0015653
2014-03-13 07:48 niffiwan Note Added: 0015654
2014-03-13 07:49 niffiwan Note Edited: 0015654
2014-03-13 07:50 niffiwan Note Edited: 0015654
2014-03-13 07:50 niffiwan File Deleted: 3019-ext-cam.png
2014-03-13 07:50 niffiwan File Deleted: 3019-norm-cam.png
2014-03-13 07:52 niffiwan Note Edited: 0015654
2014-03-13 11:37 niffiwan Note Edited: 0015654
2014-03-13 12:36 niffiwan Note Added: 0015655
2014-03-13 12:36 niffiwan Assigned To => niffiwan
2014-03-13 12:36 niffiwan Status new => assigned
2014-03-13 12:37 niffiwan Note Edited: 0015655
2014-03-13 22:26 Axem Note Added: 0015656
2014-03-14 08:55 niffiwan Changeset attached => fs2open trunk r10493
2014-03-14 08:55 niffiwan Note Added: 0015659
2014-03-14 08:55 niffiwan Status assigned => resolved
2014-03-14 08:55 niffiwan Resolution open => fixed