# Painting over textures using Cinder

**URL:** <https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899>\
**Category:** Using Cinder\
**Created:** [October 12, 2017, 12:52pm UTC](https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899 "2017-10-12T12:52:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Iseko](https://avatars.discourse-cdn.com/v4/letter/i/ce7236/32.png) [@Iseko](https://discourse.libcinder.org/u/Iseko)\
**Post date:** [October 12, 2017, 12:52pm UTC](https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899/1 "2017-10-12T12:52:41Z")

</div>

Hello, I’m quite new, and I have a problem.

Generally speaking, what I’m trying to do is Photoshop’s stamp tool. For those who don’t know what it is, it’s a tool which takes pixels from one part of the images and copies them somewhere else using a brush, which may be any alpha shape.

I’ve done it, but stumbled upon performance issues. I guess there’s a way to make it better.

_What I’m doing:_

1. My brush (B) is a two-dimensional array with float values for each pixel. [0.0, 1.0]
2. The image is a surface (S1) AND a texture (T1). I change T1 only once, when I’m done with painting.
3. There is a second surface (S2), which is used to paint stuff over S1.
4. As long as a mouse button is down, I copy pixels from S1 to S2 using a vector and B as alpha.
5. **This step causes performance issues**. I convert S2 to a texture (T2) every single time mouse moves as long as a button is down.
6. I render T1, then T2
7. As soon as a mouse button is up, I merge S2 and T1.

As a pseudocode:

```
Variables:
	Mouse position _position_;
	Mouse position difference _dpos_ = |old_position - position|;
	Mouse button _button_;
	Brush _brush_ as a two-dimensional array with values [0.0, 1.0];
	Vector _vec_ that defines where to copy from;
	Surface S1, S2;
	Texture T1, T2;

STAMP:

	repeat
		if button down then do
			if(dpos>0) then do
				for each pixel(x,y) in brush down
					S2(position + (x,y)) <- S1(position + (x,y) - vec) * pixel(x,y)
					
				T2 <- S2 // this step causes performance issues			
		else
			if S2 not empty then do
				S1 <- T1 + T2
				T1 <- S1
				clear T2
				clear S2
		draw T1
		draw T2

```

I know that it slows down because I continuously move things from CPU/RAM to GPU. I’m not sure how to avoid that though.I though about creating a second texture with a shift and paint a white mask instead of texture, but I would still need to make Surface to Texture conversion every single mouse move.

---

<div class="post-metadata">

**Author:** ![lithium](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/lithium/32/38_2.png) [@lithium](https://discourse.libcinder.org/u/lithium)\
**Post date:** [October 12, 2017, 3:52pm UTC](https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899/2 "2017-10-12T15:52:25Z")

</div>

Perhaps you could use a `PBO`?

---

<div class="post-metadata">

**Author:** ![Iseko](https://avatars.discourse-cdn.com/v4/letter/i/ce7236/32.png) [@Iseko](https://discourse.libcinder.org/u/Iseko)\
**Post date:** [October 13, 2017, 9:03am UTC](https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899/3 "2017-10-13T09:03:04Z")

</div>

I’ll take a look, thanks.

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [October 13, 2017, 9:11am UTC](https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899/4 "2017-10-13T09:11:10Z")

</div>

Hi,

welcome to Cinder! This sort of thing can better be done on the GPU entirely. Create an `Fbo` that will act as the surface to draw on, create a `Texture` for your brush and then simply bind the `Fbo`, draw the texture with alpha blending enabled, unbind the `Fbo`.

See the [FboBasic](https://github.com/cinder/Cinder/blob/2ed1866403744fd40a08dcff1c331c6d9476646b/samples/_opengl/FboBasic/src/FboBasicApp.cpp#L37-L64) sample for implementation details. For more general information on what an `Fbo` actually is, see the excellent articles on [www.learnopengl.com](https://learnopengl.com/#!Advanced-OpenGL/Framebuffers).

-Paul

---

<div class="post-metadata">

**Author:** ![Iseko](https://avatars.discourse-cdn.com/v4/letter/i/ce7236/32.png) [@Iseko](https://discourse.libcinder.org/u/Iseko)\
**Post date:** [October 13, 2017, 10:08am UTC](https://discourse.libcinder.org/t/painting-over-textures-using-cinder/899/5 "2017-10-13T10:08:09Z")

</div>

Thanks! Although alpha of the brush remains the same, the pixels change as long as one moves the mouse. Therefore I would need three textures and a fragment shader to blend them (since it’s important to draw on a different layer than the source texture). I think I’m going to try to duplicate the texture and shift it. Then I’m going to use Fbo and a shader to blend the two textures together using shifted brush texture. This should work if I’m not mistaken.
