OpenGL Python là gì?

Lưu ý rằng để biên dịch PyOpenGL_accelerate, bạn sẽ cần phải có một môi trường biên dịch tiện ích mở rộng Python đang hoạt động

Học PyOpenGL

Nếu bạn chưa quen với PyOpenGL, bạn có thể muốn bắt đầu với trang hướng dẫn OpenGLContext. Các hướng dẫn đó yêu cầu OpenGLContext, [là một trình bao bọc lớn bao gồm toàn bộ công cụ tạo cảnh, trình phân tích cú pháp VRML97, nhiều bản trình diễn, v.v.], bạn có thể cài đặt nó với

$ pip2.7 install "OpenGLContext-full==3.1.1"

Hoặc bạn có thể sao chép nó [bao gồm cả các nguồn hướng dẫn] với

$ git clone //github.com/mcfletch/openglcontext.git

hoặc [để sử dụng GitHub]

$ git clone //github.com/mcfletch/pyopengl.git

Các trang tài liệu rất hữu ích để tra cứu các tham số và ngữ nghĩa của lệnh gọi PyOpenGL

Chạy thử nghiệm

Bạn có thể chạy bộ thử nghiệm PyOpenGL từ kiểm tra mã nguồn, bạn sẽ cần

  • git [để thanh toán]

  • GLUT [GLUT miễn phí]

  • Thư viện GLExtrusion [libgle]

  • GLU [thường khả dụng trên mọi máy hỗ trợ OpenGL]

  • độc tố [pip cài đặt độc tố]

Chạy bộ thử nghiệm từ thanh toán cấp cao nhất trông giống như

$ tox

Kết quả là rất nhiều thử nghiệm được chạy trong một ma trận các môi trường. Tất cả các môi trường sẽ kéo vào pygame, một số cũng sẽ kéo vào numpy. Một số sẽ tăng tốc, và một số sẽ không

Đối với những người thực sự thiếu kiên nhẫn, bạn có thể thử chạy mã trong hình ảnh giới thiệu ở trên. Nếu điều này hoạt động, một cửa sổ sẽ mở trên màn hình của bạn với nền màu đỏ. Nếu bây giờ bạn muốn hiểu cách thức hoạt động của nó, bạn sẽ phải đọc văn bản bên dưới

Sau khi xem xét một số khái niệm OpenGL quan trọng, đã đến lúc viết mã cho ví dụ quad của chúng ta. Tuy nhiên, trước khi sử dụng OpenGL, chúng ta cần mở một cửa sổ có ngữ cảnh GL hợp lệ. Điều này có thể được thực hiện bằng bộ công cụ như Gtk, Qt hoặc Wx hoặc bất kỳ bộ công cụ gốc nào [Windows, Linux, OSX]. Thật không may, giao diện Tk Python không cho phép tạo ngữ cảnh GL và chúng tôi không thể sử dụng nó. Lưu ý rằng cũng tồn tại các bộ công cụ chuyên dụng như GLFW hoặc GLUT và lợi thế của GLUT là nó đã được cài đặt cùng với OpenGL. Ngay cả khi nó hiện không được dùng nữa, chúng tôi sẽ sử dụng GLUT vì đây là bộ công cụ rất nhẹ và không yêu cầu bất kỳ gói bổ sung nào. Đây là một thiết lập tối thiểu sẽ mở một cửa sổ có rác trên đó [vì chúng tôi thậm chí không xóa cửa sổ]

import sys
import OpenGL.GL as gl
import OpenGL.GLUT as glut

def display[]:
    glut.glutSwapBuffers[]

def reshape[width,height]:
    gl.glViewport[0, 0, width, height]

def keyboard[ key, x, y ]:
    if key == b'\x1b':
        sys.exit[ ]

glut.glutInit[]
glut.glutInitDisplayMode[glut.GLUT_DOUBLE | glut.GLUT_RGBA]
glut.glutCreateWindow['Hello world!']
glut.glutReshapeWindow[512,512]
glut.glutReshapeFunc[reshape]
glut.glutDisplayFunc[display]
glut.glutKeyboardFunc[keyboard]
glut.glutMainLoop[]

Ghi chú

Bạn sẽ không có quyền truy cập vào bất kỳ lệnh GL nào trước khi

program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
5 được thực thi vì sẽ không có ngữ cảnh OpenGL nào trước khi lệnh này được thực thi

program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
6 cho OpenGL biết thuộc tính ngữ cảnh GL là gì. Ở giai đoạn này, chúng tôi chỉ cần một bộ đệm hoán đổi [chúng tôi vẽ trên một bộ đệm trong khi bộ đệm khác được hiển thị] và chúng tôi sử dụng bộ đệm màu RGBA 32 bit đầy đủ [8 bit cho mỗi kênh]. Hàm gọi lại
program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
7 thông báo cho OpenGL về kích thước cửa sổ mới trong khi phương thức
program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
8 cho OpenGL biết phải làm gì khi cần vẽ lại. Trong trường hợp đơn giản này, chúng tôi chỉ yêu cầu OpenGL hoán đổi bộ đệm [điều này tránh nhấp nháy]. Cuối cùng, cuộc gọi lại bàn phím cho phép chúng tôi thoát bằng cách nhấn phím
program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
9

Bây giờ cửa sổ của bạn đã được tạo, chúng ta có thể bắt đầu viết chương trình của mình, tức là chúng ta cần viết một đỉnh và một trình đổ bóng phân đoạn. Đối với vertex shader, mã rất đơn giản vì chúng ta đã quan tâm đến việc sử dụng tọa độ thiết bị chuẩn hóa để mô tả quad của chúng ta trong phần trước. Điều này có nghĩa là các đỉnh không cần phải được chuyển đổi. Tuy nhiên, chúng tôi phải quan tâm đến việc gửi tọa độ 4D mặc dù chúng tôi sẽ chỉ truyền tọa độ 2D [

$ git clone //github.com/mcfletch/openglcontext.git
00] nếu không kết quả cuối cùng sẽ không được xác định. Đối với tọa độ
$ git clone //github.com/mcfletch/openglcontext.git
01, chúng tôi sẽ chỉ đặt nó thành
$ git clone //github.com/mcfletch/openglcontext.git
02 [nhưng bất kỳ giá trị nào cũng được] và đối với tọa độ
$ git clone //github.com/mcfletch/openglcontext.git
03, chúng tôi đặt nó thành
$ git clone //github.com/mcfletch/openglcontext.git
04 [xem phần giải thích]. Cũng lưu ý các cách khác [đã nhận xét] để viết trình đổ bóng

Đối với trình đổ bóng phân đoạn, nó thậm chí còn đơn giản hơn. Chúng tôi đặt màu thành màu đỏ được mô tả bởi bộ dữ liệu

$ git clone //github.com/mcfletch/openglcontext.git
05 trong ký hiệu RGBA được chuẩn hóa.
$ git clone //github.com/mcfletch/openglcontext.git
04 cho kênh alpha có nghĩa là mờ hoàn toàn

Chúng tôi đã viết trình đổ bóng của mình và bây giờ chúng tôi cần xây dựng một chương trình sẽ liên kết đỉnh và trình đổ bóng phân đoạn với nhau. Xây dựng chương trình như vậy tương đối đơn giản [miễn là chúng tôi không kiểm tra lỗi]. Trước tiên, chúng tôi cần yêu cầu các vị trí chương trình và trình đổ bóng từ GPU

program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]

Bây giờ chúng tôi có thể yêu cầu biên dịch các shader của chúng tôi thành các đối tượng GPU và chúng tôi ghi lại bất kỳ lỗi nào từ trình biên dịch [e. g. lỗi cú pháp, biến không xác định, v.v.]

Sau đó, chúng tôi liên kết hai đối tượng của mình vào một chương trình và một lần nữa, chúng tôi kiểm tra lỗi trong quá trình

$ git clone //github.com/mcfletch/openglcontext.git
0

và chúng ta có thể loại bỏ các shader, chúng sẽ không được sử dụng lại [bạn có thể coi chúng là các tệp

$ git clone //github.com/mcfletch/openglcontext.git
07 trong C]

$ git clone //github.com/mcfletch/pyopengl.git
0

Cuối cùng, chúng tôi biến chương trình thành chương trình mặc định được chạy. Chúng tôi có thể làm điều đó ngay bây giờ vì chúng tôi sẽ sử dụng một chương trình duy nhất trong ví dụ này

$ git clone //github.com/mcfletch/pyopengl.git
1

Tiếp theo, chúng ta cần xây dựng dữ liệu CPU và bộ đệm GPU tương ứng sẽ chứa một bản sao của dữ liệu CPU [GPU không thể truy cập bộ nhớ CPU]. Trong Python, mọi thứ được hỗ trợ rất nhiều bởi NumPy, cho phép kiểm soát chính xác các biểu diễn số. Điều này rất quan trọng vì GLES 2. 0 float phải dài chính xác 32 bit và float Python thông thường sẽ không hoạt động [chúng thực sự tương đương với C

$ git clone //github.com/mcfletch/openglcontext.git
08]. Vì vậy, hãy để chúng tôi chỉ định một mảng NumPy chứa float 4×2 32 bit sẽ tương ứng với các đỉnh 4×[x,y] của chúng tôi

Sau đó, chúng tôi tạo trình giữ chỗ trên GPU mà chưa chỉ định kích thước

Bây giờ chúng ta cần liên kết bộ đệm với chương trình, nghĩa là đối với mỗi thuộc tính có trong chương trình vertex shader, chúng ta cần báo cho OpenGL biết nơi tìm dữ liệu tương ứng [i. e. bộ đệm GPU] và điều này yêu cầu một số tính toán. Chính xác hơn, chúng ta cần cho GPU biết cách đọc bộ đệm để liên kết từng giá trị với thuộc tính có liên quan. Để làm điều này, GPU cần biết bước tiến giữa 2 phần tử liên tiếp là gì và độ lệch để đọc một thuộc tính là gì

$ git clone //github.com/mcfletch/pyopengl.git
3

Trong kịch bản quad đơn giản của chúng tôi, điều này tương đối dễ viết vì chúng tôi có một thuộc tính duy nhất ["

$ git clone //github.com/mcfletch/openglcontext.git
09"]. Trước tiên, chúng tôi yêu cầu vị trí thuộc tính bên trong chương trình và sau đó chúng tôi liên kết bộ đệm với phần bù có liên quan

$ git clone //github.com/mcfletch/pyopengl.git
5

Về cơ bản, chúng tôi đang cho chương trình biết cách liên kết dữ liệu với thuộc tính có liên quan. Điều này được thực hiện bằng cách cung cấp bước tiến của mảng [có bao nhiêu byte giữa mỗi bản ghi] và độ lệch của một thuộc tính nhất định

Bây giờ hãy điền dữ liệu CPU của chúng tôi và tải nó lên bộ đệm GPU mới được tạo

Chúng ta đã hoàn tất, bây giờ chúng ta có thể viết lại chức năng hiển thị

$ git clone //github.com/mcfletch/pyopengl.git
6

Nhân vật

Một hình tứ giác màu đỏ được hiển thị bằng Python, các liên kết OpenGL thô và GLUT đáng kính

Các đối số

$ git clone //github.com/mcfletch/pyopengl.git
00 trong
$ git clone //github.com/mcfletch/pyopengl.git
01 cho OpenGL biết chúng tôi muốn hiển thị 4 đỉnh từ bộ đệm hoạt động hiện tại của chúng tôi và chúng tôi bắt đầu từ đỉnh 0. Bạn sẽ có được hình bên phải với cùng màu đỏ [nhàm chán]. Toàn bộ nguồn có sẵn từ code/chapter-03/glute-quad-solid. py

Tất cả các thao tác này đều cần thiết để hiển thị một ô màu duy nhất trên màn hình và độ phức tạp có thể tăng lên khá nhiều nếu bạn thêm nhiều đối tượng, hình chiếu, ánh sáng, kết cấu, v.v. Đây là lý do tại sao chúng tôi sẽ ngừng sử dụng giao diện OpenGL thô để chuyển sang thư viện. Chúng tôi sẽ sử dụng thư viện gumpy, chủ yếu là vì tôi đã viết nó, nhưng cũng vì nó cung cấp sự tích hợp chặt chẽ với numpy. Tất nhiên, bạn có thể thiết kế thư viện của riêng mình để dễ dàng viết các ứng dụng GL Python

Nhân vật

Hình tứ giác màu xanh lam được hiển thị bằng cách sử dụng biến

$ git clone //github.com/mcfletch/pyopengl.git
02 chỉ định màu của hình tứ giác

Trong ví dụ trước, chúng tôi đã mã hóa cứng màu đỏ bên trong mã nguồn trình đổ bóng phân đoạn. Nhưng nếu chúng ta muốn thay đổi màu từ bên trong chương trình Python thì sao? . May mắn thay, có một giải pháp đơn giản do OpenGL cung cấp.

$ git clone //github.com/mcfletch/pyopengl.git
02. Đồng phục, không giống như các thuộc tính, không thay đổi từ đỉnh này sang đỉnh khác và đây chính xác là những gì chúng ta cần trong trường hợp của mình. Do đó, chúng tôi cần sửa đổi một chút trình đổ bóng phân đoạn của mình để sử dụng màu đồng nhất này

$ tox
1

Tất nhiên, chúng ta cũng cần tải một màu lên vị trí thống nhất mới này và điều này dễ dàng hơn so với thuộc tính vì bộ nhớ đã được cấp phát trên GPU [vì kích thước đã biết và không phụ thuộc vào số lượng đỉnh]

$ tox
2

Nếu bạn chạy mã mới/glut-quad-uniform-color. py, bạn sẽ nhận được hình tứ giác màu xanh lam như hình bên phải

Nhân vật

Một quad màu sử dụng màu trên mỗi đỉnh

Cho đến bây giờ, chúng tôi đã sử dụng một màu không đổi cho bốn đỉnh của hình tứ giác của chúng tôi và kết quả là [không ngạc nhiên] một hình tứ giác màu đỏ hoặc xanh đồng nhất nhàm chán. Chúng ta có thể làm cho nó thú vị hơn một chút bằng cách gán các màu khác nhau cho mỗi đỉnh và xem OpenGL sẽ nội suy màu như thế nào. Trình tạo bóng đỉnh mới của chúng tôi sẽ cần phải được viết lại thành

program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
0

Chúng tôi vừa thêm thuộc tính mới

$ git clone //github.com/mcfletch/pyopengl.git
04 nhưng chúng tôi cũng đã thêm một loại biến mới.
$ git clone //github.com/mcfletch/pyopengl.git
05. Loại này thực sự được sử dụng để truyền một giá trị từ trình tạo bóng đỉnh sang trình tạo bóng phân đoạn. Như bạn có thể đoán, loại
$ git clone //github.com/mcfletch/pyopengl.git
05 có nghĩa là giá trị này sẽ không cố định trên các mảnh khác nhau mà sẽ được nội suy tùy thuộc vào vị trí tương đối của mảnh trong tam giác, như tôi đã giải thích trong phần. Lưu ý rằng chúng tôi cũng phải viết lại trình đổ bóng phân đoạn của mình cho phù hợp, nhưng bây giờ
$ git clone //github.com/mcfletch/pyopengl.git
07 sẽ là đầu vào

program  = gl.glCreateProgram[]
vertex   = gl.glCreateShader[gl.GL_VERTEX_SHADER]
fragment = gl.glCreateShader[gl.GL_FRAGMENT_SHADER]
1

Bây giờ chúng ta cần tải màu đỉnh lên GPU. Chúng ta có thể tạo một bộ đệm dành riêng cho đỉnh mới và liên kết nó với thuộc tính mới

$ git clone //github.com/mcfletch/pyopengl.git
04, nhưng có một giải pháp thú vị hơn. Thay vào đó, chúng tôi sẽ sử dụng một mảng có nhiều mảng và một bộ đệm duy nhất, tận dụng lợi thế của mảng có cấu trúc NumPy

Tại sao nên sử dụng OpenGL trong Python?

OpenGL là giao diện lập trình ứng dụng [API] đa ngôn ngữ, đa nền tảng để hiển thị đồ họa vector 2D và 3D. API thường được sử dụng để tương tác với đơn vị xử lý đồ họa [GPU], để đạt được kết xuất được tăng tốc phần cứng .

OpenGL có sẵn cho Python không?

Trước hết, PyOpenGL chỉ là một số liên kết Python [một số mã Python hoạt động giống như một loại trình bao quanh mã gốc], vì vậy bạn có thể thao tác với OpenGL trong ngữ cảnh của Python< . OpenGL là một API đa ngôn ngữ, vì vậy bạn có thể mang kiến ​​thức về OpenGL của mình sang các ngôn ngữ khác. . OpenGL is a cross-language API, so you can take your knowledge of OpenGL to other languages.

Thư viện GL trong Python là gì?

Mô-đun này cung cấp quyền truy cập vào Thư viện đồ họa đồ họa Silicon . Nó chỉ khả dụng trên các máy Đồ họa Silicon.

OpenGL trong đồ họa máy tính là gì?

OpenGL [Thư viện đồ họa mở] là API tiêu chuẩn công nghiệp, đa nền tảng, được tăng tốc phần cứng, không phụ thuộc vào ngôn ngữ để sản xuất đồ họa 3D [bao gồm cả 2D]. Modern computers have dedicated GPU [Graphics Processing Unit] with its own memory to speed up graphics rendering.

Chủ Đề