今天做一个画图程序,类似给一个白纸,
然后用类似印章的图形点哪里就在哪里出现。

Unity在处理Texture2D上只有对像素进行操作,
所以要用到GL的一些方法,执行效率可能会更高。

代码比较简单,直接贴上应该能看懂。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//复制一个Texture到另外一个Texture.
public class CDrawTexture : MonoBehaviour
{Material nowMat;    Texture2D nowTexture;   //当前纹理RectInt nowWH;  //宽高Color clearColor = new Color(0f, 0f, 0f, 0f);   //清除的色值public void InitDrawTexture(){nowMat = PrefabList.inst.SpriteDefault;}public Texture2D CreateNewTexture(int w, int h){Clear();nowWH = new RectInt(0, 0, w, h);nowTexture = new Texture2D(w, h);FillColor(nowTexture, clearColor);return nowTexture;}public void Clear(){if (nowTexture != null){DestroyImmediate(nowTexture);}}public Texture2D CopyTexture(Texture2D source,Vector3 penpos){RenderTexture renderTexture = RenderTexture.GetTemporary(nowWH.width, nowWH.height);RenderTexture.active = renderTexture;//清空 GLGL.Clear(false, true, clearColor);//把source渲染到GLRenderGLStuff(nowWH.width, nowWH.height, nowMat, nowTexture, nowWH.width, nowWH.height, -new Vector3(nowWH.width, nowWH.height,0f)/2);//把目标渲染到GLRenderGLStuff(nowWH.width, nowWH.height, nowMat, source, source.width, source.height, penpos * globalData.pixUnit);//读取 RenderTexture 到材质 nowTexturenowTexture.ReadPixels(new Rect(0, 0, nowWH.width, nowWH.height), 0, 0);nowTexture.Apply();RenderTexture.active = null;RenderTexture.ReleaseTemporary(renderTexture);return nowTexture;}//把某个颜色填充static void FillColor(Texture2D t, Color c){RenderTexture renderTexture = RenderTexture.GetTemporary(t.width, t.height);RenderTexture.active = renderTexture;GL.Clear(false, true, c);//读取 RenderTexture 到材质 nowTexturet.ReadPixels(new Rect(0, 0, t.width, t.height), 0, 0);t.Apply();RenderTexture.active = null;RenderTexture.ReleaseTemporary(renderTexture);}/// <summary>/// 把一个Texture复制到另外一个Texture/// </summary>/// <param name="width">目标纹理大小</param>/// <param name="height">目标纹理大小</param>/// <param name="material"></param>/// <param name="source">复制的纹理</param>/// <param name="sw">复制的纹理宽</param>/// <param name="sh">复制的纹理高</param>/// <param name="penpos">鼠标位置</param>static void RenderGLStuff(int width, int height, Material material, Texture2D source, float sw, float sh, Vector3 penpos){material.SetPass(0);GL.PushMatrix();//GL入栈GL.LoadPixelMatrix(0, width, height, 0);Graphics.DrawTexture(new Rect(0, 0, 0, 0), source);GL.LoadOrtho(); //转换为正交投影变换GL.Begin(GL.QUADS);float szWidth = sw / width;float szHeight = sh / height;Vector2 at = new Vector2((penpos.x + width / 2f) / width, (penpos.y + height / 2f) / height);GL.TexCoord2(0, 0); GL.Vertex3(at.x + 0f, at.y + 0f, 0f);   //设置纹理和顶点坐标GL.TexCoord2(1, 0); GL.Vertex3(at.x + szWidth, at.y + 0f, 0f);GL.TexCoord2(1, 1); GL.Vertex3(at.x + szWidth, at.y + szHeight, 0f);GL.TexCoord2(0, 1); GL.Vertex3(at.x + 0f, at.y + szHeight, 0f);GL.End();GL.PopMatrix(); //GL出栈}
}

在其他脚本调用:

public void PaintXY(Vector3 pos){if (nowTool == null)return;pos.z = Mathf.Abs(nowMaskObj.transform.position.z - myCamera.transform.position.z);Vector3 at = myCamera.ScreenToWorldPoint(pos);Vector3 lo = nowMaskObj.transform.InverseTransformPoint(at);gameRoot.inst.drawTexture.CopyTexture(PrefabList.inst.tPen,lo);//Debug.Log("PaintXY :" + lo );checkValue = true;}

下面是写代码中遇到的一些知识点,总结在下面。

如果只是对纹理的复制,可以用下面的方法

        if (SystemInfo.copyTextureSupport == UnityEngine.Rendering.CopyTextureSupport.None){//High GC allocs hereColor[] pixelBuffer = source.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);nowTexture.SetPixels(pixelBuffer);nowTexture.Apply();}else{Graphics.CopyTexture(source, 0, 0, (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height, nowTexture, 0, 0, 0, 0);}

另外关于Graphics.DrawTexture的一些高级用法,也研究了下,并做一些记录。

public static void DrawTexture(Rect screenRect, Texture texture, Material mat = null, int pass = -1);
public static void DrawTexture(Rect screenRect, Texture texture, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Material mat = null, int pass = -1);
public static void DrawTexture(Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Material mat = null, int pass = -1);
public static void DrawTexture(Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Color color, Material mat = null, int pass = -1);
ParametersscreenRect    Rectangle on the screen to use for the texture. In pixel coordinates with (0,0) in the upper-left corner.
texture Texture to draw.
sourceRect  Region of the texture to use. In normalized coordinates with (0,0) in the bottom-left corner.
leftBorder  Number of pixels from the left that are not affected by scale.
rightBorder Number of pixels from the right that are not affected by scale.
topBorder   Number of pixels from the top that are not affected by scale.
bottomBorder    Number of pixels from the bottom that are not affected by scale.
color   Color that modulates the output. The neutral value is (0.5, 0.5, 0.5, 0.5). Set as vertex color for the shader.
mat Custom Material that can be used to draw the texture. If null is passed, a default material with the Internal-GUITexture.shader is used.
pass    If -1 (default), draws all passes in the material. Otherwise, draws given pass only.

这里的sourRect参数可以实现复制纹理中的部分,例如图集中的一块。
但是这里要注意,在这里踩了大坑。一直搞不对,原来这个参数的范围是0~1之间的。 文档中竟然只字未提,可恶,只是说0,0点是左下角。下来的4个Border应该是9宫格用法了,没用上,直接写0就好了。

下面是一个测试例子。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class NewBehaviourScript : MonoBehaviour
{Rect rect = new Rect(1034, 644, 445, 606);Rect nowWH = new Rect(0, 0, 445, 606);public Texture2D nowTexture;   //当前纹理public SpriteRenderer sprite;public Texture2D source;// Start is called before the first frame updatevoid Start(){nowTexture = new Texture2D((int)nowWH.width, (int)nowWH.height, TextureFormat.ARGB32, false);Sprite nowMaskSprite = Sprite.Create(nowTexture, new Rect(0, 0, nowTexture.width, nowTexture.height), new Vector2(0.5f, 0.5f));sprite.sprite = nowMaskSprite;}void OnGUI(){if (Event.current.type.Equals(EventType.Repaint)){//Graphics.DrawTexture(new Rect(0f, 0f, 800, 800), text);RenderTexture renderTexture = RenderTexture.GetTemporary((int)nowWH.width, (int)nowWH.height, 0);RenderTexture.active = renderTexture;//清空 GLGL.Clear(false, true, Color.clear);Rect x = new Rect(rect.x / source.width, ((source.height - rect.y- rect.height) / source.height), (rect.width ) / source.width, rect.height/ source.height);GL.PushMatrix();//GL入栈//使用Graphics类直接进行Texture绘制时,由于属于直接绘制到平面上,//所以需要转换到平面像素空间内,所以需要用到LoadPixelMatrix方法GL.LoadPixelMatrix(0, nowWH.width, nowWH.height,0);// (int)(r.x*r.width/2048), r.width, r.height, (int)(r.y * r.height / 2048));//x = new Rect(0f, 0f, 1f, 1f);Graphics.DrawTexture(nowWH, source, x, 0, 0, 0, 0);GL.PopMatrix(); //GL出栈Rect s = new Rect(0f, 0f, 1f, 1f);nowTexture.ReadPixels(nowWH, 0, 0);nowTexture.Apply();RenderTexture.active = null;RenderTexture.ReleaseTemporary(renderTexture);}}
}

source是我做的一个测试图。

new Rect(1034, 644, 445, 606);
这个区域就是想获得的图片

运行效果

Unity把Texture2D复制到坐标点击处的Texture2D相关推荐

  1. 3dmax导入unity问题(1) 轴角度坐标

    3dmax用FBX格式把模型导出并导入unity时需要注意的问题. 目录 二.轴心位置问题 2.1.一个物体 2.2.两个物体 2.3 分部分导出 三.角度问题 3.1.问题研究 3.2.解决方案操作 ...

  2. Unity 组件批量复制

    Unity Component批量复制 在制作毕设的过程中,我发现我的角色模型需要替换,但是原角色物体上有很多组件,如果全部在Inspector面板右键Copy.Paste很麻烦,所以制作了一个能够将 ...

  3. Leaflet中添加标记、折线、圆圈、多边形、弹窗显示点击处坐标

    场景 Leaflet快速入门与加载OSM显示地图: Leaflet快速入门与加载OSM显示地图_BADAO_LIUMANG_QIZHI的博客-CSDN博客 在上面加载显示地图的基础上,怎样实现添加标记 ...

  4. MATLAB提取图片点击处的坐标代码(仅供参考)

    当初写这个小程序是为了提取图片点击处的坐标,每张照片自动循环进行标点,不用一张一张手动输入.我想提取手势图片的21个点的坐标. x=dir('D:\MATLAB\work\rename1.m*.jpg ...

  5. Unity将世界坐标转为UI坐标

    Unity将世界坐标转为UI坐标 话不多说,直接上代码: public void World2ToUI(Vector3 wpos, RectTransform uiTarget){//初始化一个屏幕坐 ...

  6. autojs关于适配安卓所有分辨率的坐标点击方法

    普通交流群698307198欢迎加入v群,和各位大神一同交流 免责声明:本博客提供的所有内容仅供学习.分享与交流,我们不保证内容的正确性.通过使用本博客内容随之而来的问题与本博客无关.当使用本博客代码 ...

  7. Unity实现在Android或IOS端点击【InputField】输入框弹出键盘上的内容默认处于选中状态

    Unity实现在Android或IOS端点击[InputField]输入框弹出键盘上的内容默认处于选中状态 最终效果如: 上代码 using UnityEngine.EventSystems;/// ...

  8. qt创建右键菜单,显示在鼠标点击处

    引言 给窗口创建右键菜单,右键的时候,右键菜单出现在鼠标点击处.同时设置右键菜单的样式,右键菜单为圆角,起初设置样式的时候,右键菜单的背景在圆角边缘会出现黑色的方角,不能很好的显示为圆角,后来设置了右 ...

  9. JS实现鼠标点击处烟花爆炸效果

    JS实现鼠标点击处烟花爆炸效果(面向对象版) 程序由网上开源"JS实现放烟花效果"代码改编,实现在鼠标点击处出现烟花爆炸效果. 改编前 源码link https://github. ...

最新文章

  1. html网站开发与php网站开发_海南网站开发,网站建设,商城网站,功能性网站开发...
  2. Andriod --- JetPack (三):ViewModel 的诞生
  3. 计算机研究生上课时间自由吗,计算机在职研究生面授班主要的上课时间安排是怎样的呢...
  4. 【ABAP】BASE64加密及解密
  5. android 扫描所有文件大小,Android获取指定文件大小
  6. linux centos 7 crontab 启动,CentOS 7 Linux执行crontab 计划任务实操 - 好应网
  7. mysql数据库设计三大范式_数据库设计三大范式详解
  8. 如何绑定多个action到一个slot
  9. 2017.10.16 水管局长水管局长数据加强版 思考记录
  10. 【ElasticSearch】Es 源码之 AsyncSearchMaintenanceService 源码解读
  11. 测试开发之测试方法第二篇
  12. HTML 动画(一)
  13. 数据库管理系统属于计算机应用,数据库管理系统属于应用软件吗?
  14. python输入一个三位数输出百位十位个位_编程实现:输入一个三位数,输出其百位、十位、个位上的数字。_学小易找答案...
  15. 2000份简历模板 唯美时尚简约个人简历模板 英文简历模板 简历封面 自荐信下载
  16. 褚霸:阿里云数据库要放大招!
  17. 自己用java写一个http和https代理服务器
  18. 优效时钟屏保-一款极简风格的时钟屏保
  19. 【自动化】车间自动化十大必备装置!
  20. Windows查看及修改tomcat端口

热门文章

  1. error: src refspec test does not match any.
  2. 学习密度与专注力 By 刘未鹏
  3. apache ii评分怎么评_APACHEII评分表-新(最新整理)
  4. 本特利3500/42M 140734-02 前置器地震监测仪
  5. 微信小程序公众号开发
  6. ubuntu 卸载php7.2,ubuntu18.04 安装与卸载 php7.2
  7. mac笔记本开发环境——常用功能记录
  8. python基础之字典的更新复制
  9. 【Y忍冬草】Qt+OpenCV之Basler相机外触发开发
  10. 【python可视化】汇总中国的省市图,并且带经纬度边界