In this Python Modern Opengl programming i want to show you Coloring Triangle . so before this we had some article on Python Modern Opengl and also window creation with GLFW.
Python Modern Opengl Coloring Triangle
Now let’s create our example, So this is the complete code for Python Modern Opengl Coloring Triangle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import glfw from OpenGL.GL import * import OpenGL.GL.shaders import numpy as np def main(): if not glfw.init(): return window = glfw.create_window(720, 600, "Pyopengl Coloring Triangle", None, None) if not window: glfw.terminate() return glfw.make_context_current(window) #Postions #Colors triangle = [-0.5,-0.5,0.0, 1.0,0.0,0.0, 0.5,-0.5,0.0, 0.0, 1.0, 0.0, 0.0,0.5,0.0 , 0.0,0.0,1.0] # convert to 32bit float triangle = np.array(triangle, dtype = np.float32) VERTEX_SHADER = """ #version 330 in vec3 position; in vec3 color; out vec3 newColor; void main() { gl_Position = vec4(position, 1.0); newColor = color; } """ FRAGMENT_SHADER = """ #version 330 in vec3 newColor; out vec4 outColor; void main() { outColor = vec4(newColor, 1.0f); } """ # Compile The Program and shaders shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(VERTEX_SHADER,GL_VERTEX_SHADER), OpenGL.GL.shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER)) #Create Buffer object in gpu VBO = glGenBuffers(1) #Bind the buffer glBindBuffer(GL_ARRAY_BUFFER, VBO) glBufferData(GL_ARRAY_BUFFER, 72, triangle, GL_STATIC_DRAW) #get the position from shader position = glGetAttribLocation(shader, 'position') glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0)) glEnableVertexAttribArray(position) # get the color from shader color = glGetAttribLocation(shader, 'color') glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12)) glEnableVertexAttribArray(color) glUseProgram(shader) glClearColor(0.0,0.0,1.0,1.0) while not glfw.window_should_close(window): glfw.poll_events() glClear(GL_COLOR_BUFFER_BIT) #Draw Triangle glDrawArrays(GL_TRIANGLES, 0, 3) glfw.swap_buffers(window) glfw.terminate() if __name__ == "__main__": main() |
These are the triangle vertices and also different color for the vertices
1 2 3 4 |
#Postions #Colors triangle = [-0.5,-0.5,0.0, 1.0,0.0,0.0, 0.5,-0.5,0.0, 0.0, 1.0, 0.0, 0.0,0.5,0.0 , 0.0,0.0,1.0] |
You need to convert your vertices to 32bit float using Numpy.
1 |
triangle = np.array(triangle, dtype = np.float32) |
And these the vertex and fragment shaders
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
VERTEX_SHADER = """ #version 330 in vec3 position; in vec3 color; out vec3 newColor; void main() { gl_Position = vec4(position, 1.0); newColor = color; } """ FRAGMENT_SHADER = """ #version 330 in vec3 newColor; out vec4 outColor; void main() { outColor = vec4(newColor, 1.0f); } """ |
So in the vertex shader at the top we have the version of shader, after that we have two input values for our position and color. also we have an output value for our color that we will use that in the fragment shader.
OK now in the fragment shader we have the same shader version and we are going to take the input value of new color in our fragment shader.
What Are Shaders?
Shaders are little programs that rest on the GPU. These programs are run for each specific section of the graphics pipeline. So In a basic sense, shaders are nothing more than programs transforming inputs to outputs. Shaders are also very isolated programs.
Vertex Shader
The vertex shader is a program on the graphics card that processes each vertex and its attributes as they appear in the vertex array. Its duty is to output the final vertex position in device coordinates and to output any data the fragment shader requires. That’s why the 3D transformation should take place here. The fragment shader depends on attributes like the color and texture coordinates, which will usually be passed from input to output without any calculations.
Fragment Shader
So the output from the vertex shader is interpolated over all the pixels on the screen covered by a primitive. These pixels are called fragments and this is what the fragment shader operates on. Just like the vertex shader it has one mandatory output, the final color of a fragment. It’s up to you to write the code for computing this color from vertex colors, texture coordinates and any other data coming from the vertex shader.
In this line of code we compile the program and shaders
1 2 |
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(VERTEX_SHADER,GL_VERTEX_SHADER), OpenGL.GL.shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER)) |
The next step is to upload this vertex data to the graphics card. This is important because the memory on your graphics card is much faster and you won’t have to send the data again every time your scene needs to be rendered (about 60 times per second).
This is done by creating a Vertex Buffer Object (VBO):
1 |
VBO = glGenBuffers(1) |
To upload the actual data to it you first have to make it the active object by calling glBindBuffer()
1 |
glBindBuffer(GL_ARRAY_BUFFER, VBO) |
GL_ARRAY_BUFFER this is a type of buffer and also there different types of buffer for right now the are not important.
Also Now it is time to copy the vertex data
1 |
glBufferData(GL_ARRAY_BUFFER, 72, triangle, GL_STATIC_DRAW) |
- GL_STATIC_DRAW: So the vertex data will be uploaded once and drawn many times (e.g. the world).
- GL_DYNAMIC_DRAW: The vertex data will be created once, changed from time to time, but drawn many times more than that.
- GL_STREAM_DRAW: The vertex data will be uploaded once and drawn once.
So run the complete code and this will be the result
Subscribe and Get Free Video Courses & Articles in your Email