From fabf6910ab423ddf6562f6ea94c48f621271134b Mon Sep 17 00:00:00 2001 From: Ishan Bansal <75624384+sudoyolo@users.noreply.github.com> Date: Mon, 15 Aug 2022 20:25:43 +0530 Subject: [PATCH] Initial Commit --- README.md | 17 +++++ requirements.txt | 4 ++ tute1.py | 27 ++++++++ tute2.py | 85 +++++++++++++++++++++++ tute3.py | 174 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 307 insertions(+) create mode 100644 README.md create mode 100644 requirements.txt create mode 100644 tute1.py create mode 100644 tute2.py create mode 100644 tute3.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..bd0e017 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Introduction to PyOpenGL + +A basic introduction to PyOpenGL (using GLFW for GUI). + +## Requirements +``` +pip install -r requirements.txt +``` + +## Tutorial 1 +Creating a GLFW Window. + +## Tutorial 2 +Drawing a static triangle in the GLFW Window. + +## Tutorial 3 +Creating an animated cubical crate. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ec88dbf --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +pyopengl==3.1.6 +glfw==2.5.4 +pyrr==0.10.3 +pillow==8.4.0 \ No newline at end of file diff --git a/tute1.py b/tute1.py new file mode 100644 index 0000000..148dd14 --- /dev/null +++ b/tute1.py @@ -0,0 +1,27 @@ +import glfw + +# initializing glfw library +if not glfw.init(): + raise Exception("glfw can not be initialized!") + +# creating the window +window = glfw.create_window(600, 600, "My OpenGL window", None, None) + +# check if window was created +if not window: + glfw.terminate() + raise Exception("glfw window can not be created!") + +# set window's position +glfw.set_window_pos(window, 650, 250) + +# make the context current +glfw.make_context_current(window) + +# the main application loop +while not glfw.window_should_close(window): + glfw.poll_events() + glfw.swap_buffers(window) + +# terminate glfw, free up allocated resources +glfw.terminate() \ No newline at end of file diff --git a/tute2.py b/tute2.py new file mode 100644 index 0000000..1153d5b --- /dev/null +++ b/tute2.py @@ -0,0 +1,85 @@ +import glfw +from OpenGL.GL import * +from OpenGL.GL.shaders import compileProgram, compileShader +import numpy as np + +vertex_src = """ +# version 330 + +in vec3 a_position; +in vec3 a_color; + +out vec3 v_color; + +void main() +{ + gl_Position = vec4(a_position, 1.0); + v_color = a_color; +} +""" + +fragment_src = """ +# version 330 + +in vec3 v_color; +out vec4 out_color; + +void main() +{ + out_color = vec4(v_color, 1.0); +} +""" + +# initializing glfw library +if not glfw.init(): + raise Exception("glfw can not be initialized!") + +# creating the window +window = glfw.create_window(600, 600, "My OpenGL window", None, None) + +# check if window was created +if not window: + glfw.terminate() + raise Exception("glfw window can not be created!") + +# set window's position +glfw.set_window_pos(window, 650, 250) + +# make the context current +glfw.make_context_current(window) + +vertices = [-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] + +vertices = np.array(vertices, dtype=np.float32) + +shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER)) + +VBO = glGenBuffers(1) +glBindBuffer(GL_ARRAY_BUFFER, VBO) +glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) + +position = glGetAttribLocation(shader, "a_position") +glEnableVertexAttribArray(position) +glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0)) + +color = glGetAttribLocation(shader, "a_color") +glEnableVertexAttribArray(color) +glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12)) + +glUseProgram(shader) +glClearColor(0, 0.1, 0.1, 1) + +# the main application loop +while not glfw.window_should_close(window): + glfw.poll_events() + + glClear(GL_COLOR_BUFFER_BIT) + + glDrawArrays(GL_TRIANGLES, 0, 3) + + glfw.swap_buffers(window) + +# terminate glfw, free up allocated resources +glfw.terminate() diff --git a/tute3.py b/tute3.py new file mode 100644 index 0000000..0af0ebc --- /dev/null +++ b/tute3.py @@ -0,0 +1,174 @@ +import glfw +from OpenGL.GL import * +from OpenGL.GL.shaders import compileProgram, compileShader +import numpy as np +import pyrr +from PIL import Image + +vertex_src = """ +# version 330 + +layout(location = 0) in vec3 a_position; +layout(location = 1) in vec3 a_color; +layout(location = 2) in vec2 a_texture; + +uniform mat4 rotation; + +out vec3 v_color; +out vec2 v_texture; + +void main() +{ + gl_Position = rotation * vec4(a_position, 1.0); + v_color = a_color; + v_texture = a_texture; + + //v_texture = 1 - a_texture; // Flips the texture vertically and horizontally + //v_texture = vec2(a_texture.s, 1 - a_texture.t); // Flips the texture vertically +} +""" + +fragment_src = """ +# version 330 + +in vec3 v_color; +in vec2 v_texture; + +out vec4 out_color; + +uniform sampler2D s_texture; + +void main() +{ + out_color = texture(s_texture, v_texture); // * vec4(v_color, 1.0f); +} +""" + +# glfw callback functions +def window_resize(window, width, height): + glViewport(0, 0, width, height) + +# initializing glfw library +if not glfw.init(): + raise Exception("glfw can not be initialized!") + +# creating the window +window = glfw.create_window(600, 600, "My OpenGL window", None, None) + +# check if window was created +if not window: + glfw.terminate() + raise Exception("glfw window can not be created!") + +# set window's position +glfw.set_window_pos(window, 650, 250) + +# set the callback function for window resize +glfw.set_window_size_callback(window, window_resize) + +# make the context current +glfw.make_context_current(window) + +vertices = [-0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, + -0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0, + + -0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, + 0.5, 0.5, -0.5, 0.0, 0.0, 1.0, 1.0, 1.0, + -0.5, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 1.0, + + 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, + 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, + 0.5, -0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0, + + -0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0, + -0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, + -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, + -0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0, + + -0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0, + 0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, + 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, + -0.5, -0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0, + + 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0, + -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, + -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0, + 0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0] + +indices = [0, 1, 2, 2, 3, 0, + 4, 5, 6, 6, 7, 4, + 8, 9, 10, 10, 11, 8, + 12, 13, 14, 14, 15, 12, + 16, 17, 18, 18, 19, 16, + 20, 21, 22, 22, 23, 20] + +vertices = np.array(vertices, dtype=np.float32) +indices = np.array(indices, dtype=np.uint32) + +shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER)) + +# Vertex Buffer Object +VBO = glGenBuffers(1) +glBindBuffer(GL_ARRAY_BUFFER, VBO) +glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) + +# Element Buffer Object +EBO = glGenBuffers(1) +glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO) +glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW) + +glEnableVertexAttribArray(0) +glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(0)) + +glEnableVertexAttribArray(1) +glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(12)) + +glEnableVertexAttribArray(2) +glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(24)) + +texture = glGenTextures(1) +glBindTexture(GL_TEXTURE_2D, texture) + +# Set the texture wrapping parameters +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) +# Set texture filtering parameters +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) + +# load image +image = Image.open("images/crate.jpg") +image = image.transpose(Image.FLIP_TOP_BOTTOM) +img_data = image.convert("RGBA").tobytes() +# img_data = np.array(image.getdata(), np.uint8) # second way of getting the raw image data +glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data) + +glUseProgram(shader) +glClearColor(0, 0.1, 0.1, 1) +glEnable(GL_DEPTH_TEST) +glEnable(GL_BLEND) +glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + +rotation_loc = glGetUniformLocation(shader, "rotation") + +# the main application loop +while not glfw.window_should_close(window): + glfw.poll_events() + + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) + + rot_x = pyrr.Matrix44.from_x_rotation(0.5 * glfw.get_time()) + rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time()) + + glUniformMatrix4fv(rotation_loc, 1, GL_FALSE, pyrr.matrix44.multiply(rot_x, rot_y)) + + glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None) + + glfw.swap_buffers(window) + +# terminate glfw, free up allocated resources +glfw.terminate()