jrbudda / Vivecraft_112

VR mod for Minecraft. For Minecraft version 1.12.2
http://www.vivecraft.org/
Other
126 stars 31 forks source link

GUI transparency erases previous GUI pixels #145

Open talchas opened 4 years ago

talchas commented 4 years ago

The default BlendFunc used all over the place in minecraft is tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO). This is fine when rendering to a framebuffer, but not fine when rendering to a texture where the alpha value matters - drawing a sprite with transparent regions effectively erases anything previously drawn beneath it in the transparent region.

This can be seen in a few places: JEI category/page text, highlighted items in the jei recipe window, dragging item stacks over the right/left jei panes. 2020-04-08_17 05 31 Forestry worktables with a locked recipe (unless they're a recipe with >1 item output, which works by accident because FontRenderer.drawString leaves ALPHA_TEST enabled). 2020-04-08_17 08 50 EIO tanks have half-transparent buckets drawn over some slots, which now are partially transparent. Basically any modded GUI that shows a fluid will be rendering a translucent fluid texture, which now shows up rendered directly over the world.

The ultra dumb hack of

    public static void tryBlendFuncSeparate(int srcFactor, int dstFactor, int srcFactorAlpha, int dstFactorAlpha)
    {
        if (srcFactorAlpha == SourceFactor.ONE.factor && dstFactorAlpha == DestFactor.ZERO.factor) {
            srcFactorAlpha = SourceFactor.ONE_MINUS_DST_ALPHA.factor;
            dstFactorAlpha = DestFactor.ONE.factor;
        }
seems to fix most of these issues, though the jei left/right pane issues remain, as do the amusing fluid issues. Surprisingly it doesn't seem to cause any new visible rendering issues.
Techjar commented 4 years ago

Patching the GlStateManager is clever but some mods are directly calling the GL14 function, which obviously bypasses that. We're supposed to be ignoring the alpha channel when drawing the GUI into the world so I don't know why it's still appearing transparent. You could try turning on menu background which changes the clear color to solid black when a screen is open.

Also, it drives me up a fucking wall that nobody seems to understand how glBlendFuncSeparate works. The correct usage is as follows: tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE) You just want the alpha values to add up, not subtract or anything. I guess ONE_MINUS_DST_ALPHA is more correct in regards to not overflowing the value, but implementations clamp it internally so it doesn't really matter.

talchas commented 4 years ago

Yeah, there is no correct value for the alpha components in BlendFuncSeparate with rendering arbitrary inputs to a temporary texture like this - you want alpha = 1 - (1-dstalpha) * (1-srcalpha) to get the same as if you didn't have the temporary texture, but you can't get that out of opengl's fixed pipeline afaik. Any of the various sensible options are better than the ONE/ZERO minecraft used as the default and every mod copypastaed.