By GL function with pictures and other related functions

  We know the process inside screen after screen images can be processed by the material, when we want to deal with the general picture, GL direct call function by Graphics.Blit function on the line, a package according to their own habits Blit method: 

    public static void Blit(Texture source, Material material, RenderTexture destination, int materialPass = 0)
    {
        if(material.SetPass(materialPass))
        {
            material.mainTexture = source;
            Graphics.SetRenderTarget(destination);

            GL.PushMatrix();
            GL.LoadOrtho();

            GL.Begin(GL.QUADS);
            {
                Vector3 coords = new Vector3(0, 0, 0);
                GL.TexCoord(coords);
                GL.Vertex(coords);

                coords = new Vector3(1, 0, 0);
                GL.TexCoord(coords);
                GL.Vertex(coords);

                coords = new Vector3(1, 1, 0);
                GL.TexCoord(coords);
                GL.Vertex(coords);

                coords = new Vector3(0, 1, 0);
                GL.TexCoord(coords);
                GL.Vertex(coords);
            }
            GL.End();

            GL.PopMatrix();
        }
    }

  Because Graphics.SetRenderTarget method is passed RenderTexture, rendered the RenderTexture not directly as such as Texture2D or Cubemap or Texture3D to use, generally require a second conversion. Texture2D Take as an example, the conversion method looks like there are so few, down take a look: 

0. each variable

    public Material material;
    public Texture2D input;

    public Texture2D outPutTex2D;
    public RenderTexture renderTexture;

 

1. Using the pointer the way, in general, if RenderTexture memory like Texture2D then use Texture2D RenderTexture related directly to the address should be on it, because there is no official documents directly on the test code: 

    private void Start()
    {
        if(renderTexture == false)
        {
            renderTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
        }
        renderTexture.hideFlags = HideFlags.DontSave;
        outPutTex2D = Texture2D.CreateExternalTexture(Screen.width, Screen.height, TextureFormat.ARGB32, false, true, renderTexture.GetNativeTexturePtr());
        // ArgumentException: nativeTex can not be null
    }

  Get it GetNativeTexturePtr before rendering RenderTexture does not work, change it error, and then get after rendering complete words: 

    private void Start()
    {
        if(renderTexture == false)
        {
            renderTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
        }
        renderTexture.hideFlags = HideFlags.DontSave;
        Blit(input, material, renderTexture);
        var nativeTexturePtr = renderTexture.GetNativeTexturePtr();
        if(nativeTexturePtr != System.IntPtr.Zero)
        {
            outPutTex2D = Texture2D.CreateExternalTexture(Screen.width, Screen.height, TextureFormat.ARGB32, false, true, nativeTexturePtr);
        }
    }

  Directly on the collapse, although the break to see it nativeTexturePtr can really get into, but think RenderTexture not specified when creating that kind of memory, a direct pointer to create Texture2D should be that it will collapse.

  Because official documents had nothing to write, it is estimated that road leads nowhere ...

 

2. Use Texture2D.ReadPixels method, this is the most common method: 

    private void Start()
    {
        int W = (int)Screen.width;
        int H = (int)Screen.height;
        if(renderTexture == false)
        {
            renderTexture = RenderTexture.GetTemporary(W, H, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
        }
        renderTexture.hideFlags = HideFlags.DontSave;
        outPutTex2D = new Texture2D(W, H, TextureFormat.ARGB32, false, true);
        
        Blit(input, material, renderTexture);
        
        var current = RenderTexture.active;
        RenderTexture.active = renderTexture;
        outPutTex2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        outPutTex2D.Apply();
        RenderTexture.active = current;
    }

  The most commonly used, the result is correct to say nothing, just worrying efficiency

 

3. Call Graphics.CopyTexture copy pictures: 

    private void Start()
    {
        int W = (int)Screen.width;
        int H = (int)Screen.height;
        if(renderTexture == false)
        {
            renderTexture = RenderTexture.GetTemporary(W, H, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
        }
        renderTexture.hideFlags = HideFlags.DontSave;
        outPutTex2D = new Texture2D(W, H, TextureFormat.ARGB32, false, true);
        
        Blit(input, material, renderTexture);
        
        if((SystemInfo.copyTextureSupport & UnityEngine.Rendering.CopyTextureSupport.RTToTexture) != 0)
        {
            Graphics.CopyTexture(renderTexture, outPutTex2D);
        }
    }

  This should be the address pointer using the above copying encapsulation efficiency of Leverage. And does not require a corresponding type.

 

 

Guess you like

Origin www.cnblogs.com/tiancaiwrk/p/11957545.html