0

So I have a Unity3D plugin written in c++ and compiled for Android.

When I started off I used OpenGLES2 to maximize device reach but recently I decided I wanted to try moving up to OpenGLES3, so I included the gl3 headers instead of the gl2 headers, built, and switched Graphics API on Unity to OpenGLES3.

Unfortunately, it is not working correctly anymore.

The code is the following:

In one plugin I have this:

glBindTexture(GL_TEXTURE_2D, textureID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, videoWidth, videoHeight, glPixFormat, glPixType, frameBuffer->buff);

where textureID is a pointer to a texture passed by Unity, and framebuffer->buff is the bytearray of the image I want to put in it.

In a second plugin I have this:

static std::vector<unsigned char> emptyPixelsAlpha(height * width, 0);

glBindTexture(GL_TEXTURE_2D, alphaID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, emptyPixelsAlpha.data());

where alphaID is a pointer to a texture passed by Unity. (I simplified this part a bit, what it does in this case is simply fill another texture of the same dimensions of the previous one with black on a single channel)

These two textures are fed to the following shader on Unity side:

 Shader "alphaMaskShader"
 {
    Properties{
      _MainTex("Base (RGB)", 2D) = "white" {}
      _Alpha("Alpha (A)", 2D) = "white" {} 
    }
    SubShader{
        Tags{ "RenderType" = "Transparent" "Queue" = "Overlay" }

        ZWrite Off
        ZTest Off

        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask RGB

        Pass{
            SetTexture[_MainTex]{
            Combine texture
            }
            SetTexture[_Alpha]{
            Combine previous, texture
            }
        }
    }
}

Before, this code would simply make the displayed texture completely invisible since the "alphaID" texture becomes the alpha channel. Instead, it now displays the "textureID" texture as if the alpha channel isn't there or that it's somehow set to complete opaqueness.

I read over the OpenGLES3 specs but it clearly states that it's backward compatible with OpenGLES2 and haven't found much about porting issues.

UB-
  • 123
  • 3
  • 12
  • From an API point of view it is forward compatible, so it's likely the bug is in Unity. Please post a complete example, including the rendering API sequence and shaders - anything could be going wrong in Unity to cause this. https://stackoverflow.com/help/mcve – solidpixel Feb 07 '18 at 16:43
  • @solidpixel I frankly don't know what that means, these are the relevant parts of openGL calls on the c++ side, on unity side I posted the shader and the only thing missing are the two texture2D constructors which are respectively called with texture format ARGB32 and Alpha8.. Looking around I got a hunch that maybe the setTexture calls aren't working anymore for some reason. – UB- Feb 09 '18 at 16:56
  • BTW I opened up GAPID (Graphics API Debugger for those of you who never heard of it, it intercepts and stores your graphics driver calls for opengl and vulkan applications) and traced my application. When I looked at the trace I surprisingly found that the frames it stored are showing the expected result (texture is transparent)! That quite blew my mind. How can what GAPID sees and what my screen shows be different?! – UB- Feb 09 '18 at 16:58

1 Answers1

0

I found what the problem was. Apparently something has changed with how GL_ALPHA works between ES 2.0 and 3.0 (or 3.2 since that's what my device is on).

I got it working again by swapping GL_ALPHA with GL_RED.

EDIT: This apparently only works on Oreo devices, the problem still persists on Nougat. I've created a dedicated question to this issue: Simple OpenGL ES 3 function works on Oreo but not on Nougat

UB-
  • 123
  • 3
  • 12