项目分享:https://github.com/Claymoreno1/RenderTexture
这一次添加了水平翻转、垂直翻转、顺时针旋转、逆时针旋转,关闭图像,保存,退出功能;对RT的创建和销毁做了一些更改。
界面如下:
关于选择的C#部分
public void clockwise()
{
clockw = true;
rotate();
}
public void anticlockwise()
{
anclockw = true;
rotate();
}
private void rotate()//旋转shader更新
{
if (Gamevars.textureisable)
{
rotatematerial.SetInt("_Clockwise", clockw ? 1 : 0);
rotatematerial.SetInt("_AnuiClockwise", anclockw? 1:0);
RenderTexture Disttexture =RenderTexture.GetTemporary(texture.height, texture.width, 0);//因为旋转之后宽高对调
Graphics.Blit(texture, Disttexture, rotatematerial);
int width = Disttexture.width;
int height = Disttexture.height;
Gamevars.imagewidth = width;
Gamevars.imageheight = height;//更新控制结构体
Viewtexture = new Texture2D(width, height, TextureFormat.ARGB32, false);
RenderTexture.active = Disttexture;
Viewtexture.ReadPixels(new Rect(0, 0, width, height),0, 0);
Viewtexture.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(Disttexture);
texture = Viewtexture;
updateBSC();
image.GetComponent<RectTransform>().sizeDelta = new Vector2(width,height);
Sprite sprite = Sprite.Create(Viewtexture, new Rect(0, 0,width, height), new Vector2(0.5f, 0.5f));
image.sprite = sprite;
Refresh();
}
clockw = false;
anclockw = false;
}
shader部分非常简单
Shader "myshaders/rotate"
{
Properties
{
_MainTex ("_MainTex", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
int _Clockwise;
int _AnuiClockwise;
struct v2a
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (v2a v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
if(_Clockwise==1){
i.uv=mul(float2x2(0,-1,1,0),i.uv);
}
if(_AnuiClockwise==1){
i.uv=mul(float2x2(0,1,-1,0),i.uv);
}
fixed4 renderTex = tex2D(_MainTex,i.uv);
return fixed4(renderTex);
}
ENDCG
}
}
Fallback Off
}
翻转的C#部分
public void horizon()
{
overturnX = true;
Overturn();
}
public void vertical()
{
overturnY = true;
Overturn();
}
private void Overturn()//翻转shader更新
{
if (Gamevars.textureisable)
{
overturnmaterial.SetInt("_Horizon", overturnX ? 1 : 0);
overturnmaterial.SetInt("_Vertical", overturnY ? 1 : 0);
RenderTexture Disttexture = RenderTexture.GetTemporary(texture.width, texture.height, 0);
Graphics.Blit(texture, Disttexture, overturnmaterial);
int width = Disttexture.width;
int height = Disttexture.height;
Viewtexture = new Texture2D(width, height, TextureFormat.ARGB32, false);
RenderTexture.active = Disttexture;
Viewtexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
Viewtexture.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(Disttexture);
texture = Viewtexture;//因为旋转之后,仍需要其他shader参与
updateBSC();
image.GetComponent<RectTransform>().sizeDelta = new Vector2(Viewtexture.width, Viewtexture.height);
Sprite sprite = Sprite.Create(Viewtexture, new Rect(0, 0, Viewtexture.width, Viewtexture.height), new Vector2(0.5f, 0.5f));
image.sprite = sprite;
Refresh();
}
overturnX = false;
overturnY = false;
}
翻转的shader部分
Shader "myshaders/overturn"
{
Properties
{
_MainTex ("_MainTex", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
int _Horizon;
int _Vertical;
struct v2a
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (v2a v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
if(_Horizon==1){
i.uv.x=1-i.uv.x;
}
if(_Vertical==1){
i.uv.y=1-i.uv.y;
}
fixed4 renderTex = tex2D(_MainTex,i.uv);
return fixed4(renderTex);
}
ENDCG
}
}
Fallback Off
}
这两个功能的实现都非常简单,尤其是shader部分,但是我现在遇到了一个问题,当对一张图片进行大量操作之后,内存占用量很大
现在我的方法是在关闭图像的时候趁机重新加载一次scene
public void fileclose()
{
if (Gamevars.textureisable)
{
Gamevars.textureisable = false;
selectfile.gameObject.SetActive(true);
Gamevars.size = 1;
size1.text = ((int)(Gamevars.size * 100)).ToString() + "%";
image.color = new Color32(255, 255, 255, 0);
image.transform.position = new Vector3(0, 720, 0);
slider1.value = 1;
slider2.value = 1;
slider3.value = 1;
SceneManager.LoadScene(0);
}
}
关于内存占用问题有什么好方法的话,还请大佬给我留言
最后保存代码
public void savefile()
{
if (Gamevars.textureisable)
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "请选择保存位置";
dialog.Filter = "图像文件(*.png)|*.png";
if (dialog.ShowDialog() == DialogResult.OK)
{
byte[] bytes = Viewtexture.EncodeToPNG();
File.WriteAllBytes(dialog.FileName, bytes);
}
}
}
目前只能保存为PNG格式。。
在下一次,我会添加裁剪功能,和解决内存占用问题。上课去了。。。