# Why is this simple (I think?) program flickering?

**URL:** <https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352>\
**Category:** OPENRNDR\
**Created:** [March 14, 2022, 3:53am UTC](https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352 "2022-03-14T03:53:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sourmike](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/sourmike/32/363_2.png) [@sourmike](https://openrndr.discourse.group/u/sourmike)\
**Post date:** [March 14, 2022, 3:53am UTC](https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352/1 "2022-03-14T03:53:11Z")

</div>

Hey everyone, first-time poster here 🤓

I just started working with OPENRNDR. I have this rotating plumbob/gem program I’m working on, and since I added in some triangles via the contour tool, they always flicker in a weird way for me. I’ve attached the code and a video recording of my screen. I’m guessing it has something to do with `depthWrite` stuff not being optimized as well for custom shapes. If someone could enlighten me as to why this is happening and any potential solutions I would very much appreciate it!

![plumbob-flicker](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/63b296ddcbb76cde676bf9e5fb5d74f6a75a7c4c.gif)

```auto
import org.openrndr.PresentationMode
import org.openrndr.Program
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.DepthTestPass
import org.openrndr.extra.olive.oliveProgram
import org.openrndr.extra.color.presets.DARK_SEA_GREEN
import org.openrndr.extra.color.presets.DIM_GRAY
import org.openrndr.extra.color.presets.SEA_GREEN
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
import org.openrndr.shape.contour
import kotlin.math.PI
import kotlin.math.sin

fun main() = application {
    configure {
        width = 800
        height = 800

    }
    oliveProgram {

        extend {
            drawer.clear(ColorRGBa.DIM_GRAY)
            fun setup() {
                drawer.translate(0.0, 0.0, -400.0)
                drawer.perspective(90.0, 1.0, 1.0, -300.0)
                drawer.depthWrite = true
                drawer.depthTestPass = DepthTestPass.LESS_OR_EQUAL
                drawer.stroke = ColorRGBa.DARK_SEA_GREEN
                drawer.strokeWeight = 5.0
                drawer.fill = ColorRGBa.SEA_GREEN
            }

            val ratioAS = 0.866
            val apothem = 100
            val side = apothem/ratioAS
            val rectWidth = side
            val rectHeight = 80.0

            val tempo = seconds * 0.5

            for (num in (0..5)) {
                setup()
                val offset = (PI/3.0) * num
                drawer.translate(
                    (sin(tempo + offset)) * apothem,
                    0.0,
                    sin(tempo + (0.5 * PI) + offset) * 100.0)
                drawer.rotate(
                    Vector3(0.0, 1.0, 0.0),
                    tempo * (360.0/(2.0* PI)) + (360.0 * (num/6.0))
                )

                drawer.rectangle(
                    -(rectWidth/2.0),
                    -(rectHeight/2.0),
                    rectWidth,
                    rectHeight
                )
                drawer.strokeWeight = 5.0
                val triangleWidth = rectWidth - drawer.strokeWeight
                drawer.translate(0.0, ((rectHeight + drawer.strokeWeight)/2.0));
                drawer.rotate(Vector3(1.0, 0.0, 0.0), -28.0)
                val c = contour {
                    moveTo(Vector2(-triangleWidth/2.0, 0.0))
                    lineTo(cursor + Vector2(triangleWidth, 0.0))
                    lineTo(cursor + Vector2(-triangleWidth/2.0, 200.0))
                    lineTo(anchor)
                    close()
                }
                drawer.contour(c)

                drawer.defaults()
            }

        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [March 14, 2022, 8:34am UTC](https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352/2 "2022-03-14T08:34:00Z")

</div>

Hi @sourmike ! Welcome to the forum 🙂

I had that same issue in the past. The issue is that most drawing operations are optimized for 2D, not for 3D. The current options for combining fills with contours in 3D are limited. Some places to look into 3D drawing are

- [Custom rendering - OPENRNDR GUIDE](https://guide.openrndr.org/advancedDrawing/customRendering.html)
- [orx/orx-mesh-generators at master · openrndr/orx · GitHub](https://github.com/openrndr/orx/tree/master/orx-mesh-generators)
- [OPENRNDR & Processing - Texture Cube](https://openrndr.discourse.group/t/openrndr-processing-texture-cube/97)

I’ll post again if I have an example to run.

btw. I tweaked your code to show some helper functions:

> **imports**
>
> ```auto
> import org.openrndr.application
> import org.openrndr.color.ColorRGBa
> import org.openrndr.draw.DepthTestPass
> import org.openrndr.draw.isolated
> import org.openrndr.extras.color.presets.DARK_SEA_GREEN
> import org.openrndr.extras.color.presets.DIM_GRAY
> import org.openrndr.extras.color.presets.SEA_GREEN
> import org.openrndr.math.Polar
> import org.openrndr.math.Vector2
> import org.openrndr.math.Vector3
> import org.openrndr.math.asDegrees
> import org.openrndr.shape.Rectangle
> import org.openrndr.shape.ShapeContour
> 
> ```

```auto
fun main() = application {
    configure {
        width = 800
        height = 800
    }
    program {
        val ratioAS = 0.866
        val apothem = 100.0
        val rect = Rectangle.fromCenter(
            Vector2.ZERO, apothem / ratioAS, 80.0
        )
        val strokeW = 5.0
        val triangleWidth = rect.width - strokeW
        val tri = ShapeContour.fromPoints(
            listOf(
                Vector2(-triangleWidth / 2, 0.0),
                Vector2(triangleWidth / 2, 0.0),
                Vector2(0.0, 200.0)
            ), true
        )

        extend {
            drawer.apply {
                clear(ColorRGBa.DIM_GRAY)
                depthWrite = true
                depthTestPass = DepthTestPass.LESS_OR_EQUAL
                stroke = ColorRGBa.DARK_SEA_GREEN
                strokeWeight = strokeW
                fill = ColorRGBa.SEA_GREEN
                perspective(90.0, 1.0, 1.0, -300.0)
                translate(0.0, 0.0, -400.0)
            }

            val tempo = seconds * 0.5

            repeat (6) { num ->
                val angle = tempo.asDegrees + 60 * num
                val tr = Polar(angle, apothem).cartesian
                drawer.isolated {
                    translate(tr.y, 0.0, tr.x)
                    rotate(Vector3.UNIT_Y, angle)
                    rectangle(rect)

                    translate(0.0, (rect.height + strokeW) / 2.0);
                    rotate(Vector3.UNIT_X, -28.0)
                    contour(tri)
                }
            }
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [March 14, 2022, 9:06am UTC](https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352/3 "2022-03-14T09:06:28Z")

</div>

Here I constructed a wireframe box. The vertex data for a filled box is provided by `boxMesh()` (orx-mesh-generators). It produces triangles to be filled, but the vertices needed for the edges are different ones. In the code below I generated the 12 edges of a cube.

![apps.p5.P05_texturecubeWireframe-2022-03-14-10.05.19](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/ed4704f25562dd746f6c42792f23ae9271aba567.gif)

> **Imports**
>
> ```auto
> import org.openrndr.WindowMultisample
> import org.openrndr.application
> import org.openrndr.color.ColorRGBa
> import org.openrndr.draw.*
> import org.openrndr.extras.camera.Orbital
> import org.openrndr.extras.color.presets.DARK_SEA_GREEN
> import org.openrndr.extras.color.presets.DIM_GRAY
> import org.openrndr.extras.color.presets.SEA_GREEN
> import org.openrndr.extras.meshgenerators.boxMesh
> import org.openrndr.extra.videoprofiles.gif
> import org.openrndr.math.Vector3
> 
> ```

```auto
fun main() = application {
    configure {
        width = 400
        height = 400
        multisample = WindowMultisample.SampleCount(4)
    }
    program {
        val cam = Orbital()
        cam.eye = -Vector3.UNIT_Z * 150.0

        val cube = boxMesh()
        val cubeWire = vertexBuffer(vertexFormat {
            position(3)
        }, 12 * 2)

        val l = 0.5
        val o = -0.5
        val p = listOf(
            Vector3(o, o, o), Vector3(o, l, o), Vector3(l, l, o), Vector3(l, o, o), // front
            Vector3(o, o, l), Vector3(o, l, l), Vector3(l, l, l), Vector3(l, o, l) // back
        )
        cubeWire.put {
            write(p[0], p[1], p[1], p[2], p[2], p[3], p[3], p[0]) // front
            write(p[4], p[5], p[5], p[6], p[6], p[7], p[7], p[4]) // back
            write(p[0], p[4], p[1], p[5], p[2], p[6], p[3], p[7]) // connect front to back
        }

        // extend(ScreenRecorder()) { gif() }
        extend(cam)
        extend {
            drawer.clear(ColorRGBa.DIM_GRAY)
            drawer.scale(90.0)
            drawer.fill = ColorRGBa.SEA_GREEN
            drawer.vertexBuffer(cube, DrawPrimitive.TRIANGLES)
            drawer.fill = ColorRGBa.DARK_SEA_GREEN
            drawer.vertexBuffer(cubeWire, DrawPrimitive.LINES)
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![sourmike](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/sourmike/32/363_2.png) [@sourmike](https://openrndr.discourse.group/u/sourmike)\
**Post date:** [March 17, 2022, 3:53am UTC](https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352/4 "2022-03-17T03:53:02Z")

</div>

Hi @abe , thanks for your help! Those helpers look very convenient. I’ll see if I can wrap my head around this way of 3d modelling! 😅

---

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [March 17, 2022, 9:41am UTC](https://openrndr.discourse.group/t/why-is-this-simple-i-think-program-flickering/352/5 "2022-03-17T09:41:28Z")

</div>

There is already a method in the meshgenerators to create a `vertexBuffer` plane (to be drawn using `DrawPrimitive.TRIANGLES`). You could create another method to return a `vertexBuffer` with the edges of that plane to be drawn using `DrawPrimitive.LINES`.

Maybe you need another method for a triangles edges…

Then the code might look clean? Feel free to ask for help 🙂
