Skip to content

Commit e9f91d6

Browse files
committed
Rectangle tutorial done advanced a little on texture
Textures don't seem to not work so well. Probably I am not initializing them with correct parameters. But now the secret of draw elements is gone So textures should not be that difficult by now.
1 parent b8d3a95 commit e9f91d6

29 files changed

+463
-767
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,5 @@ If you feel like you can contribute to tutorials, they are always welcomed.
5353
As stated in the description the list is progressive.
5454

5555
1. [Hello Triangle](./tutorials/01-triangle/TriangleTutorial.ipynb)
56+
2. [Rectangle](./tutorials/02-rectangle/RectangleTutorial.ipynb)
57+
3. [Multiple VAO-VBO couples](./tutorials/03-vao-vbo/VAOsVBOs.ipynb)

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
license_str = f.read()
1212

1313
setuptools.setup(
14-
name="pyside-opengl-tutorials",
14+
name="PysideOpenGLTutorials",
1515
version="0.1",
1616
author='Kaan Eraslan',
1717
python_requires='>=3.5.0',
@@ -23,7 +23,7 @@
2323
url="https://github.com/D-K-E/pyside-opengl-tutorials",
2424
packages=setuptools.find_packages(
2525
exclude=["tests", "*.tests", "*.tests.*", "tests.*",
26-
"docs", ".gitignore", "README.md"]
26+
"docs", ".gitignore", "README.md"],
2727
),
2828
test_suite="tests",
2929
install_requires=[

tutorials/01-triangle/app.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# author: Kaan Eraslan
22
# license: see, LICENSE
33

4-
from PySide2 import QtWidgets, QtCore, QtGui
4+
from PySide2 import QtWidgets, QtCore
55
from gltriangle import TriangleGL
66
import sys
77

8+
89
def createSlider():
910
slider = QtWidgets.QSlider(QtCore.Qt.Vertical)
1011

tutorials/01-triangle/gltriangle.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,12 @@
55
import sys
66
import ctypes
77

8-
from PySide2 import QtWidgets, QtCore, QtGui
9-
from PySide2.QtGui import QVector3D
108
from PySide2.QtGui import QOpenGLVertexArrayObject
119
from PySide2.QtGui import QOpenGLBuffer
1210
from PySide2.QtGui import QOpenGLShaderProgram
1311
from PySide2.QtGui import QOpenGLShader
1412
from PySide2.QtGui import QOpenGLContext
15-
from PySide2.QtGui import QMatrix4x4
1613
from PySide2.QtGui import QVector4D
17-
from PySide2.QtGui import QColor
1814

1915
from PySide2.QtWidgets import QApplication
2016
from PySide2.QtWidgets import QMessageBox
@@ -43,7 +39,11 @@ def __init__(self, parent=None):
4339

4440
# shaders etc
4541
triangleTutoDir = os.path.dirname(__file__)
46-
shaderDir = os.path.join(triangleTutoDir, "shaders")
42+
trianglePardir = os.path.join(triangleTutoDir, os.pardir)
43+
trianglePardir = os.path.realpath(trianglePardir)
44+
mediaDir = os.path.join(trianglePardir, "media")
45+
shaderDir = os.path.join(mediaDir, "shaders")
46+
print(shaderDir)
4747
availableShaders = ["triangle"]
4848
self.shaders = {
4949
name: {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"## Rectangle Tutorial"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"Welcome to the tutorial on how to draw a rectangle using the new QtGui based OpenGL api of PySide2.\n",
15+
"\n",
16+
"As we have mentioned on the first tutorial on how to draw the `Hello Triangle`. I will be giving only the relative parts of the code and explain the differences rather than commenting everything.\n",
17+
"\n",
18+
"Let's see the final output of our application"
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": 2,
24+
"metadata": {},
25+
"outputs": [
26+
{
27+
"data": {
28+
"text/plain": [
29+
"CompletedProcess(args=['python', 'app.py'], returncode=0)"
30+
]
31+
},
32+
"execution_count": 2,
33+
"metadata": {},
34+
"output_type": "execute_result"
35+
}
36+
],
37+
"source": [
38+
"import subprocess\n",
39+
"\n",
40+
"subprocess.run([\"python\", \"app.py\"])"
41+
]
42+
},
43+
{
44+
"cell_type": "markdown",
45+
"metadata": {},
46+
"source": [
47+
"Not so bad right !"
48+
]
49+
},
50+
{
51+
"cell_type": "markdown",
52+
"metadata": {},
53+
"source": [
54+
"I am skipping the code on the window holding the gl widget. \n",
55+
"\n",
56+
"Here is the constructor of our gl widget."
57+
]
58+
},
59+
{
60+
"cell_type": "code",
61+
"execution_count": null,
62+
"metadata": {},
63+
"outputs": [],
64+
"source": [
65+
"class RectangleGL(QOpenGLWidget):\n",
66+
" \"Texture loading opengl widget\"\n",
67+
"\n",
68+
" def __init__(self, parent=None):\n",
69+
" \"Constructor\"\n",
70+
" QOpenGLWidget.__init__(self, parent)\n",
71+
" tutoTutoDir = os.path.dirname(__file__)\n",
72+
" tutoPardir = os.path.join(tutoTutoDir, os.pardir)\n",
73+
" tutoPardir = os.path.realpath(tutoPardir)\n",
74+
" mediaDir = os.path.join(tutoPardir, \"media\")\n",
75+
" shaderDir = os.path.join(mediaDir, \"shaders\")\n",
76+
" #\n",
77+
" availableShaders = [\"rectangle\", \"triangle\"]\n",
78+
" self.shaders = {\n",
79+
" name: {\n",
80+
" \"fragment\": os.path.join(shaderDir, name + \".frag\"),\n",
81+
" \"vertex\": os.path.join(shaderDir, name + \".vert\")\n",
82+
" } for name in availableShaders\n",
83+
" }\n",
84+
" self.core = \"--coreprofile\" in QCoreApplication.arguments()\n",
85+
"\n",
86+
" # opengl data related\n",
87+
" self.context = QOpenGLContext()\n",
88+
" self.program = QOpenGLShaderProgram()\n",
89+
" self.vao = QOpenGLVertexArrayObject()\n",
90+
" self.vbo = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer)\n",
91+
" \n",
92+
" # ############ Diff 1 ##########################\n",
93+
" # this is the novelty in this code. We specify #\n",
94+
" # indices of triangles that would made up #\n",
95+
" # our rectangle. Notice its data type #\n",
96+
" self.indices = np.array([\n",
97+
" 0, 1, 3, # first triangle\n",
98+
" 1, 2, 3 # second triangle\n",
99+
" ], dtype=ctypes.c_uint)\n",
100+
"\n",
101+
" # vertex data of the panel that would hold the image\n",
102+
" \n",
103+
" self.vertexData = np.array([\n",
104+
" # corners of the rectangle\n",
105+
" 0.5, 0.5, 0.0, # top right\n",
106+
" 0.5, -0.5, 0.0, # bottom right\n",
107+
" -0.5, -0.5, 0.0, # bottom left\n",
108+
" -0.5, 0.5, 0.0, # top left\n",
109+
" ], dtype=ctypes.c_float)\n",
110+
"\n",
111+
" self.rectColor = QVector4D(0.0, 1.0, 1.0, 0.0)"
112+
]
113+
},
114+
{
115+
"cell_type": "markdown",
116+
"metadata": {},
117+
"source": [
118+
"As you can see it is fairly close to the constructor of the triangle widget.\n",
119+
"The initialization is exactly the same as triangle widget so we are skipping that entirely.\n",
120+
"\n",
121+
"Let's see the drawing function."
122+
]
123+
},
124+
{
125+
"cell_type": "code",
126+
"execution_count": null,
127+
"metadata": {},
128+
"outputs": [],
129+
"source": [
130+
" def paintGL(self):\n",
131+
" \"paint gl\"\n",
132+
" funcs = self.context.functions()\n",
133+
" # clean up what was drawn\n",
134+
" funcs.glClear(pygl.GL_COLOR_BUFFER_BIT)\n",
135+
"\n",
136+
" # bind texture\n",
137+
" vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao)\n",
138+
" self.program.bind()\n",
139+
"\n",
140+
" # draw stuff\n",
141+
" ########## Diff #############\n",
142+
" # This is another drawing function in opengl\n",
143+
" # Notice that its signature is from OpenGL ES 2\n",
144+
" \n",
145+
" funcs.glDrawElements(\n",
146+
" pygl.GL_TRIANGLES,\n",
147+
" self.indices.size,\n",
148+
" pygl.GL_UNSIGNED_INT,\n",
149+
" self.indices.tobytes())\n",
150+
" # VoidPtr(self.indices.tobytes() * ctypes.sizeof(ctypes.c_uint)))\n",
151+
" vaoBinder = None\n",
152+
" self.program.release()"
153+
]
154+
},
155+
{
156+
"cell_type": "markdown",
157+
"metadata": {},
158+
"source": [
159+
"- The first parameter is the drawing mode.\n",
160+
"- The second is the number of elements that is to be drawn, since the indice specifies the index of an element that is to be drawn, it is equal to the size of indices.\n",
161+
"- We specify the type of the elements of indices\n",
162+
"- We specify the data of indices. \n",
163+
"\n",
164+
"If we want to follow documentation more closely we can also use the commented line instead of the final parameter which creates the void pointer to data of the indices"
165+
]
166+
},
167+
{
168+
"cell_type": "markdown",
169+
"metadata": {},
170+
"source": [
171+
"That's it now you know how to draw a rectangle in opengl api of pyside2"
172+
]
173+
}
174+
],
175+
"metadata": {
176+
"kernelspec": {
177+
"display_name": "Python 3",
178+
"language": "python",
179+
"name": "python3"
180+
},
181+
"language_info": {
182+
"codemirror_mode": {
183+
"name": "ipython",
184+
"version": 3
185+
},
186+
"file_extension": ".py",
187+
"mimetype": "text/x-python",
188+
"name": "python",
189+
"nbconvert_exporter": "python",
190+
"pygments_lexer": "ipython3",
191+
"version": "3.7.3"
192+
}
193+
},
194+
"nbformat": 4,
195+
"nbformat_minor": 2
196+
}

tutorials/04-cube/app.py tutorials/02-rectangle/app.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# Author: Kaan Eraslan
1+
# author: Kaan Eraslan
2+
# license: see, LICENSE
23

3-
from PySide2 import QtWidgets, QtCore, QtGui
4-
from glcube import CubeGL
4+
from PySide2 import QtWidgets, QtCore
5+
from glrectangle import RectangleGL
56
import sys
67

7-
88
def createSlider():
99
slider = QtWidgets.QSlider(QtCore.Qt.Vertical)
1010

@@ -21,7 +21,7 @@ class AppWindow(QtWidgets.QMainWindow):
2121

2222
def __init__(self, parent=None):
2323
super().__init__(parent)
24-
self.glWidget = CubeGL()
24+
self.glWidget = RectangleGL()
2525
self.xSlider = createSlider()
2626
self.ySlider = createSlider()
2727
self.zSlider = createSlider()

0 commit comments

Comments
 (0)