性能问题待修复

This commit is contained in:
shenjianxing 2025-02-24 17:03:44 +08:00
parent 8cfeecd8e8
commit 3802bfbc6b
3 changed files with 162 additions and 139 deletions

View File

@ -187,6 +187,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
captureBGImg: {fileID: 1613795782999759057}
RawImg: {fileID: 3350589312635769069}
TempImg: {fileID: 0}
Content: {fileID: 6174875567737795578}
ClearBtn: {fileID: 2761790485595999517}
BackBtn: {fileID: 8433557736356431636}

View File

@ -3,9 +3,12 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.UI;
using static UnityEditor.Progress;
@ -14,14 +17,14 @@ public class ScreenShotPainter : MonoBehaviour
{
public class LineSegment
{
public List<Vector2> Points { get; set; }
public RenderTexture Texture { get; set; }
public Color Color { get; set; }
public float Width { get; set; }
public bool IsEraser { get; set; }
public LineSegment(Color color, float width, bool isEraser)
{
Points = new List<Vector2>();
Texture = RenderTexture.GetTemporary(Screen.width, Screen.height, 24);
Color = color;
Width = width;
IsEraser = isEraser;
@ -44,11 +47,11 @@ public class ScreenShotPainter : MonoBehaviour
/// <summary>
/// 涂鸦的RenderTexture图片
/// </summary>
private RenderTexture _blitRenderTexture;
private RenderTexture _currentRenderTexture;
/// <summary>
/// 涂鸦的RenderTexture图片
/// </summary>
private RenderTexture _tempRenderTexture;
//private RenderTexture _historyRenderTexture;
/// <summary>
/// 截图灰化背景图
/// </summary>
@ -229,6 +232,14 @@ public class ScreenShotPainter : MonoBehaviour
bool isInited = false;
Status status = Status.Pen;
private CommandBuffer _commandBuffer;
private float _lastPaintTime;
private float _paintInterval = 0.02f; // 每0.02秒绘制一次
void Awake()
{
instance = this;
@ -239,6 +250,9 @@ public class ScreenShotPainter : MonoBehaviour
if (isInited == false)
{
isInited = true;
_commandBuffer = new CommandBuffer();
_commandBuffer.name = "PaintCommandBuffer";
_bgRawImage = bgRawImg;
_paintCanvasImg = drawImg;
@ -274,13 +288,12 @@ public class ScreenShotPainter : MonoBehaviour
_eraserBrushMat.SetFloat("_SizeY", _eraserSize * (float)_screenHeight / (float)_screenWidth);
_tempRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_blitRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_paintCanvasImg.texture = _blitRenderTexture;
_currentRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_paintCanvasImg.texture = _currentRenderTexture;
// 激活渲染纹理,确保它可以被写入
RenderTexture.active = _blitRenderTexture;
RenderTexture.active = _currentRenderTexture;
GL.Clear(true, true, Color.clear);
//给画布添加事件
@ -306,7 +319,7 @@ public class ScreenShotPainter : MonoBehaviour
paintEventTrigger.triggers.Add(beginDrawEntry);
// 使用 Graphics.Blit 清除渲染纹理
Graphics.Blit(null, _blitRenderTexture, _clearBrushMat);
Graphics.Blit(null, _currentRenderTexture, _clearBrushMat);
// 恢复默认的渲染纹理
RenderTexture.active = null;
@ -338,7 +351,7 @@ public class ScreenShotPainter : MonoBehaviour
_leftDownConnerPoint = Vector2.zero;
_rightUpConnerPoint = Vector2.zero;
_rightDownConnerPoint = Vector2.zero;
_blitRenderTexture.Release();
_currentRenderTexture.Release();
_bgRawImage.material.SetVector("_Rect", new Vector4(0, 0, 0, 0));
_eraserFlag = false;
//Graphics.Blit(_blitRenderTexture, _blitRenderTexture, _clearBrushMat); //清除一下
@ -458,11 +471,12 @@ public class ScreenShotPainter : MonoBehaviour
void OnPostRender()
{
Debug.LogError(" OnPostRender");
if (!enabled)
return;
if (_drawRegionRect)
{
Debug.LogError("111");
//如果材质球不存在
if (!_lineMaterial)
{
@ -555,7 +569,7 @@ public class ScreenShotPainter : MonoBehaviour
#endif
//Texture2D CombineTex = new Texture2D(_renderTex.width, _renderTex.height, TextureFormat.ARGB32, false);
RenderTexture prev = RenderTexture.active;
RenderTexture.active = _blitRenderTexture;
RenderTexture.active = _currentRenderTexture;
Texture2D BliTexture2D = new Texture2D((int)width, (int)height, TextureFormat.ARGB32, false);
@ -613,7 +627,6 @@ public class ScreenShotPainter : MonoBehaviour
case Status.Pen:
break;
case Status.Line:
case Status.Rect:
if (Input.GetMouseButton(0))
{
@ -621,24 +634,18 @@ public class ScreenShotPainter : MonoBehaviour
{
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
}
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, _eraserFlag);
}
break;
case Status.Circle:
if (_currentLine == null)
{
if (_currentLine == null)
{
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
}
_lastPoint = Input.mousePosition;
}
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
_lastPoint = Input.mousePosition;
break;
case Status.Rect:
fixedPoint = Input.mousePosition;
prePoint = fixedPoint;
break;
}
}
@ -650,52 +657,59 @@ public class ScreenShotPainter : MonoBehaviour
ChangeToEraser(this.status == Status.Eraser);
}
Vector2 fixedPoint = default;
Vector2 prePoint = default;
bool needUndo = false;
private void PaintDragging(BaseEventData data)
{
if (_enabled && _haveRegion)
{
if (Input.GetMouseButton(0))
if (Input.GetMouseButton(0) && Time.time - _lastPaintTime > _paintInterval)
{
switch (status)
_lastPaintTime = Time.time;
// 绘制逻辑
if (Input.GetMouseButton(0))
{
case Status.Pen:
case Status.Eraser:
if (_currentLine == null)
{
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
}
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, _eraserFlag);
break;
//case Status.Line:
// if (_currentLine != null)
// {
// if (_currentLine.Points.Count <= 0)
// {
// _currentLine.Points.Add(Input.mousePosition);
// LerpPaint(Input.mousePosition, false);
// }
// }
// break;
//case Status.Rect:
// if (_currentLine != null)
// {
// if (_currentLine.Points.Count <= 0)
// {
// _currentLine.Points.Add(Input.mousePosition);
// LerpPaint(Input.mousePosition, false);
// }
// }
// break;
switch (status)
{
case Status.Pen:
case Status.Eraser:
if (_currentLine == null)
{
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
}
LerpPaint(Input.mousePosition, _eraserFlag);
break;
case Status.Rect:
if (needUndo)
{
if (_lineStack.Count > 0)
{
Undo();
}
else
{
Clear();
}
needUndo = false;
}
if (Vector2.Distance(prePoint, Input.mousePosition) > 1)
{
prePoint = Input.mousePosition;
_currentLine = new LineSegment(_paintBrushMat.GetColor("_Color"), _brushSize, _eraserFlag);
_lastPoint = fixedPoint;
RectFactory();
needUndo = true;
}
break;
}
}
}
}
}
private void OnPaintEndDrag(BaseEventData data)
{
if (_enabled && _haveRegion)
@ -708,56 +722,40 @@ public class ScreenShotPainter : MonoBehaviour
{
FinishedRaw();
}
break;
case Status.Line:
if (_currentLine != null)
{
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, false);
FinishedRaw();
}
break;
case Status.Rect:
{
if (_currentLine != null)
{
var points = GenerateRectanglePoints(_lastPoint, Input.mousePosition);
_currentLine.Points.Add(points[1]);
LerpPaint(points[1], false);
_currentLine.Points.Add(Input.mousePosition);
LerpPaint(Input.mousePosition, false);
_currentLine.Points.Add(points[2]);
LerpPaint(points[2], false);
_currentLine.Points.Add(_lastPoint);
LerpPaint(points[0], false);
FinishedRaw();
}
}
fixedPoint = default;
needUndo = false;
break;
case Status.Circle:
if (_currentLine != null)
{
float radius = Vector2.Distance(_lastPoint, Input.mousePosition);
var points = GenerateCirclePoints(_lastPoint, radius);
_lastPoint = default;
foreach (var item in points)
{
_currentLine.Points.Add(item);
LerpPaint(item, false);
}
_currentLine.Points.Add(points[0]);
LerpPaint(points[0], false);
FinishedRaw();
}
break;
default:
break;
}
@ -777,40 +775,57 @@ public class ScreenShotPainter : MonoBehaviour
}
return points;
}
Vector2[] GenerateRectanglePoints(Vector2 start, Vector2 end)
public void RectFactory()
{
if (_lastPoint != default)
{
var points = GenerateRectanglePoints(_lastPoint, Input.mousePosition);
LerpPaint(points[0], false);
LerpPaint(points[1], false);
LerpPaint(points[2], false);
LerpPaint(points[3], false);
LerpPaint(points[0], false);
FinishedRaw();
}
}
public Vector2[] GenerateRectanglePoints(Vector2 start, Vector2 thirdPoint)
{
Vector2[] points = new Vector2[4];
points[0] = start;
points[3] = end;
// 原本的 end 点(这里用 thirdPoint 替代)作为数组的第三个元素
points[2] = thirdPoint;
if (start.x < end.x)
if (start.x < thirdPoint.x)
{
if (start.y < end.y)
if (start.y < thirdPoint.y)
{
// 从左下方到右上方
points[1] = new Vector2(end.x, start.y);
points[2] = new Vector2(start.x, end.y);
points[1] = new Vector2(thirdPoint.x, start.y);
points[3] = new Vector2(start.x, thirdPoint.y);
}
else
{
// 从左上方到右下方
points[1] = new Vector2(end.x, start.y);
points[2] = new Vector2(start.x, end.y);
points[1] = new Vector2(thirdPoint.x, start.y);
points[3] = new Vector2(start.x, thirdPoint.y);
}
}
else
{
if (start.y < end.y)
if (start.y < thirdPoint.y)
{
// 从右下方到左上方
points[1] = new Vector2(start.x, end.y);
points[2] = new Vector2(end.x, start.y);
points[1] = new Vector2(start.x, thirdPoint.y);
points[3] = new Vector2(thirdPoint.x, start.y);
}
else
{
// 从右上方到左下方
points[1] = new Vector2(start.x, end.y);
points[2] = new Vector2(end.x, start.y);
points[1] = new Vector2(start.x, thirdPoint.y);
points[3] = new Vector2(thirdPoint.x, start.y);
}
}
@ -820,56 +835,64 @@ public class ScreenShotPainter : MonoBehaviour
public void FinishedRaw()
{
if (_currentLine != null)
{
// 保存当前纹理到 LineSegment
RenderTexture.active = _currentLine.Texture;
Graphics.Blit(_currentRenderTexture, _currentLine.Texture);
RenderTexture.active = null;
_lineStack.Push(_currentLine);
_paintCanvasImg.texture = _currentLine.Texture;
_currentLine = null;
}
_lastPoint = Vector2.zero;
}
_lastPoint = Vector2.zero;
}
public void Undo()
{
if (_lineStack.Count > 0)
{
Clear();
// 移除最后一条线
var line = _lineStack.Pop();
//重新绘制所有剩余的线条
foreach (var item in _lineStack)
// 如果栈中还有剩余的线条,切换到上一个线条的纹理
if (_lineStack.Count > 0)
{
_paintBrushMat.SetColor("_Color", item.Color);
foreach (var point in item.Points)
{
LerpPaint(point, item.IsEraser);
}
_lastPoint = Vector2.zero;
var previousLine = _lineStack.Peek();
RenderTexture.active = _currentRenderTexture;
Graphics.Blit(previousLine.Texture, _currentRenderTexture);
RenderTexture.active = null;
_paintCanvasImg.texture = previousLine.Texture;
}
else
{
Clear();
}
}
}
public void Clear()
{
_blitRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_tempRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
// 重新分配 RenderTexture
_currentRenderTexture = RenderTexture.GetTemporary(_screenWidth, _screenHeight, 24);
_paintCanvasImg.texture = _blitRenderTexture;
// 更新画布的纹理
_paintCanvasImg.texture = _currentRenderTexture;
// 清空线条栈
_lineStack.Clear();
}
/// <summary>
/// 绘画进行插值
/// </summary>
/// <param name="point"></param>
Vector2[] vector2s = new Vector2[10000];
private void LerpPaint(Vector2 point, bool isEraser)
{
Paint(point, isEraser);
Paint(isEraser, point);
if (_lastPoint == Vector2.zero)
{
@ -881,42 +904,41 @@ public class ScreenShotPainter : MonoBehaviour
if (dis > _brushLerpSize)
{
Vector2 dir = (point - _lastPoint).normalized;
int num = (int)(dis / _brushLerpSize);
int num = (int)(dis / (_brushLerpSize));
for (int i = 0; i < num; i++)
{
Vector2 newPoint = _lastPoint + dir * (i + 1) * _brushLerpSize;
Paint(newPoint, isEraser);
vector2s[i] = _lastPoint + dir * (i + 1) * _brushLerpSize;
Paint(isEraser, vector2s[i]);
}
Debug.LogError(num);
}
_lastPoint = point;
}
// 画点方法
private void Paint(Vector2 point, bool isDraser)
private void Paint(bool isEraser, Vector2 point)
{
Material material = null;
if (point.x < _leftDownConnerPoint.x || point.x > _rightUpConnerPoint.x || point.y < _leftDownConnerPoint.y || point.y > _rightUpConnerPoint.y)
return;
Vector2 uv = new Vector2(point.x / (float)_screenWidth, point.y / (float)_screenHeight);
Vector2 uv = new Vector2(point.x / (float)_screenWidth,
point.y / (float)_screenHeight);
if (isDraser)
if (isEraser)
{
_eraserBrushMat.SetVector("_UV", uv);
// 先将源纹理内容渲染到临时纹理
Graphics.Blit(_blitRenderTexture, _tempRenderTexture, _eraserBrushMat);
// 再将临时纹理内容复制回源纹理
Graphics.Blit(_tempRenderTexture, _blitRenderTexture);
material = _eraserBrushMat;
}
else
{
_paintBrushMat.SetVector("_UV", uv);
// 先将源纹理内容渲染到临时纹理
Graphics.Blit(_blitRenderTexture, _tempRenderTexture, _paintBrushMat);
// 再将临时纹理内容复制回源纹理
Graphics.Blit(_tempRenderTexture, _blitRenderTexture);
material = _paintBrushMat;
}
}
_commandBuffer.Blit(_currentRenderTexture, _currentRenderTexture, material);
Graphics.ExecuteCommandBuffer(_commandBuffer);
_commandBuffer.Clear();
}
public Vector2 GetCaptureViewLeftDownConnerPoint()
{
Vector2 vec = new Vector2(Mathf.Min(_startPoint.x, _endPoint.x), Mathf.Min(_startPoint.y, _endPoint.y));
@ -1003,7 +1025,7 @@ public class ScreenShotPainter : MonoBehaviour
_drawRegionRect = false;
_haveRegion = false;
_haveCirmformRectStarPoint = false;
_blitRenderTexture.Release();
_currentRenderTexture.Release();
_startPoint = Vector2.zero;
_endPoint = Vector2.zero;
_leftUpConnerPoint = Vector2.zero;

View File

@ -5,7 +5,7 @@ using QFramework;
namespace QFramework.Example
{
// Generate Id:4d840482-3ece-436e-9579-de5573072430
// Generate Id:f3b60a04-6dce-45f6-968a-cb101a31a0c9
public partial class UIDraw
{
public const string Name = "UIDraw";