# One familiar triangle#

As with any graphics library guide, we also have a guide on how to draw a triangle. Below is a slightly modified line drawing code from the previous tutorial. The following code draws one triangle:

Entire source

``` 1import moderngl
2import numpy as np
3
4from PIL import Image
5
6ctx = moderngl.create_context(standalone=True)
7
8prog = ctx.program(
10        #version 330
11
12        in vec2 in_vert;
13        in vec3 in_color;
14
15        out vec3 v_color;
16
17        void main() {
18            v_color = in_color;
19            gl_Position = vec4(in_vert, 0.0, 1.0);
20        }
21    """,
23        #version 330
24
25        in vec3 v_color;
26
27        out vec3 f_color;
28
29        void main() {
30            f_color = v_color;
31        }
32    """,
33)
34
35vertices = np.asarray([
36
37    -0.75, -0.75,  1, 0, 0,
38    0.75, -0.75,  0, 1, 0,
39    0.0, 0.649,  0, 0, 1
40
41], dtype='f4')
42
43vbo = ctx.buffer(vertices.tobytes())
44vao = ctx.vertex_array(prog, vbo, "in_vert", "in_color")
45
46fbo = ctx.framebuffer(
47    color_attachments=[ctx.texture((512, 512), 3)]
48)
49fbo.use()
50fbo.clear(0.0, 0.0, 0.0, 1.0)
51vao.render()  # "mode" is moderngl.TRIANGLES by default
52
53Image.frombytes(
55    "raw", "RGB", 0, -1
56).show()
```

When you run the code you will see this:

As you may have noticed, we only specified three colors for each vertex, but OpenGL interpolates our triangle and we see a soft transition of colors.

At this point you can try out the fragment shader, for example, letâ€™s draw a lighting effect:

```#version 330

in vec3 v_color;

out vec3 f_color;

void main() {
vec2 pixel_coord = (gl_FragCoord.xy-256.0)/256.0;
f_color = v_color*(1.0-length(pixel_coord));
}
```

Shaders are not very fond of branching algorithms and operations such as `if (condition) {action} else {action}`. It is recommended to use formulas more often.