opengl 使用撤消/重做功能绘制到纹理

enxuqcxy  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(179)

我目前正在使用以下工具绘制纹理:

glTexSubImage2D();

你可以选择笔刷半径,颜色,形状等。
然后使用以下任一函数:

public void drawPoint(int px, int py);

public void drawPoints(IntQueue points);

public void drawLine(int x1, int y1, int x2, int y2);

然后是:

private void flush();

这将创建一个带有两个像素数据缓冲区的对象。一个包含“画笔笔划”之前的纹理数据,另一个包含更改。只保存受影响的区域。(纹理的子矩形)
flush()还使用glTexSubImage 2D()将更改上载到纹理
我也有一个工作撤销/重做功能。
所以这一切都很好。问题是,在绘图时,你希望看到的变化应用,而你正在绘制。这是设置的方式(使用鼠标绘图)是,你只看到你已经画了什么后,你释放鼠标按钮。如果我绘制和“刷新”每一帧,你结束了一个撤销/重做示例的每一个“点”。
一个简单的“绘制程序”是如何做到这一点的?或者一个人如何以更聪明的方式做到这一点?
我正在使用纹理作为地形的混合贴图。(红色通道=草地等)

编辑:

  • (试图理解@斯派克特的回答)*
  • 你说渲染到纹理是什么意思?我目前使用的是glTexSubImage 2D,glCopyImageSubData。你的意思是渲染四边形到fbo绑定纹理吗?每个像素一个四边形。因为我不确定是否有其他方法可以做到这一点。*

如果我没理解错的话:
1.正在编辑
假设我画了一条线。所以我开始了一个新的编辑。我有两个纹理。两个纹理包含相同的数据atp。线从鼠标位置edit start开始。每一帧(或者当鼠标移动时)我计算出从起点到当前鼠标位置创建一条线所需的所有像素,然后使用glTexSubImage 2D将这些像素上传到“front texture”。然后使用该纹理进行渲染。渲染完成后,我清除了线条留下的像素区域:将未编辑的“后纹理”的内容复制到“前纹理”。然后重复这个过程直到释放鼠标(编辑结束)。当编辑结束时,我将未编辑纹理的笔划区域保存为一个撤消对象。然后用编辑更新两个纹理(行区域)。(同时,任何当前存储的重做对象都将被处理)
1.取消
(The撤消对象存储“之前”的像素数据和笔画的面积)在撤消时,创建一个Redo对象来存储当前的“快照”(面积与撤消对象相等)。然后将撤消对象的像素上传到两个纹理中。处置撤消对象。
1.取消复原
创建一个Undo对象来存储当前状态。将Redo缓冲区上传到两个纹理。释放Redo对象。
1.问题
如何将一个纹理区域复制到另一个纹理区域?glCopyImageSubData
我应该使用帧缓冲区对象吗?还是像我现在这样“直接使用纹理”就可以了?我很好奇绘图程序是如何做到这一点的。有这么多这样的程序,一定有一些通用的方法来做这种编辑。我的方法对吗?

voase2hg

voase2hg1#

有更多的方法可以撤销/重做。2你选择了更简单但更占用内存的方法。3在这种情况下,你必须在你的纹理上渲染实际编辑过的部分。4因为这可能不是一个直接的屏幕缓冲区,你很可能在它上面做了一些其他的处理,你可以用2个纹理来简化事情。
因此,当你开始编辑一些东西,你复制原始内容到临时纹理(使用它作为一个明确的状态backbufer)。
编辑时,直接渲染到纹理中(或从临时纹理复制并重新渲染)。
在编辑结束时,您只需存储临时纹理中更改的区域。

相关问题