Afficher pyopengl dans le navigateur (python + anguille)

introduction

Dans le navigateur, OpenGL a déjà WebGL. Mais je ne peux pas utiliser de shader de calcul et d'autres shaders. La grammaire est également différente. Cependant, l'interface graphique est extrêmement meilleure avec WebGL. Facile à utiliser. Je ne pense pas que la plupart des gens utilisent pyopengl. Je pense que c'est parce que l'interface graphique ne peut pas être aidée. Un jour, je voulais faire pyopengl dans mon navigateur. Récemment, lorsque je collectais des informations pour la première fois dans EEL, [OpenCV] Afficher les images OpenCV sur l'anguille J'ai trouvé. Cela devra être fait. Je n'avais aucune connaissance du CV, donc j'étais vraiment dedans, mais j'ai pu le faire.

Code source

main.py


import eel
from OpenGL.GL import *
from OpenGL.WGL import *
from ctypes import *
from ctypes.wintypes import *
import numpy as np
import cv2
import base64
import time
import atexit

kernel32 = windll.kernel32
user32 = windll.user32
winmm = windll.winmm 
    
# window init
XRES, YRES = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
WS_OVERLAPPEDWINDOW = 0xcf0000
hWnd = user32.CreateWindowExA(0,0xC018,0,WS_OVERLAPPEDWINDOW,0,0,XRES,YRES,0,0,0,0)
hdc = user32.GetDC(hWnd)   
user32.SetForegroundWindow(hWnd)

# GL context init
PFD_SUPPORT_OPENGL = 32
PFD_DOUBLEBUFFER = 1
pfd = PIXELFORMATDESCRIPTOR(0,1,PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0)
SetPixelFormat(hdc, ChoosePixelFormat(hdc, pfd), pfd)
hGLrc = wglCreateContext(hdc)
wglMakeCurrent(hdc, hGLrc)

def finish():
    # GL context finish
    wglMakeCurrent(0, 0)
    wglDeleteContext(hGLrc)
    # windoe finish
    user32.ReleaseDC(hWnd, hdc)
    user32.PostQuitMessage(0)
    user32.DestroyWindow(hWnd)
    #print("finish")
atexit.register(finish)


def main():
    vsh = """
#version 430

layout(location = 0) in vec2 p;

void main(){
    gl_Position = vec4(p, 0, 1);
}
"""

    fsh = """
#version 430

out vec4 fragColor;

uniform vec2 resolution;
uniform float time;

void main() {
    vec2 p = (2.0 * gl_FragCoord.xy - resolution.xy) / resolution.y;
    p += vec2(cos(time), sin(time)) * 0.5;
    float g = exp(-1.5 * dot(p,p));
    fragColor = vec4(g*.3, g*.5, g, 1)+.3;
}
"""

    width = 640
    height = 350


    # GL init
    glClearColor(0, 0, 0, 1)
    glEnable(GL_CULL_FACE)
    glCullFace(GL_BACK)
    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LEQUAL)
    glViewport(0,0,width,height)
    
    program = glCreateProgram()
    for s, t in zip((vsh, fsh), (GL_VERTEX_SHADER, GL_FRAGMENT_SHADER)):    
        shader = glCreateShader(t)
        glShaderSource(shader, s)
        glCompileShader(shader)
        if glGetShaderiv(shader, GL_COMPILE_STATUS) != GL_TRUE:
            raise RuntimeError(glGetShaderInfoLog(shader).decode())
        glAttachShader(program, shader)
    glLinkProgram(program)
    glUseProgram(program)
    glUniform2f(glGetUniformLocation(program, "resolution"), width,height)
    vertices = np.array([-1,-1,1,-1,-1,1,1,1], np.float32)
    glBindBuffer(GL_ARRAY_BUFFER, glGenBuffers(1))
    glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, (c_float*len(vertices))(*vertices), GL_STATIC_DRAW)
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(0)
    
    pixels = np.zeros((height,width,3), np.uint8)
    st = time.time()
    while True:
        eel.sleep(0.01)
        elapsedTime = time.time()-st
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glUniform1f(glGetUniformLocation(program, "time"), elapsedTime)
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
        glReadPixels(0, 0, width,height, GL_BGR, GL_UNSIGNED_BYTE, pixels)
        _, image = cv2.imencode('.jpg', np.flipud(pixels))
        eel.set_base64image("data:image/jpg;base64," + base64.b64encode(image).decode())
        eel.set_elapsedtime(round(elapsedTime,1))

if __name__ == '__main__':
    eel.init('web')
    eel.start('index.html', block=False)
    main()

index.html


<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="/eel.js"></script>

        <script>
            eel.expose(set_elapsedtime);
            function set_elapsedtime(elapsedtime0) {
                document.getElementById("elapsedtime").innerHTML = "elapsedtime:" + elapsedtime0 + "s";
            }
            eel.expose(set_base64image);
            function set_base64image(img) {
                document.getElementById("python_video").src = img;
            }
        </script>
    </head>
    <body>
        <div id="elapsedtime">elapsedtime</div>
        <img id="python_video" >
    </body>
</html>

en conclusion

Il est réalisé par python + anguille. Pour plus d'informations, veuillez rechercher avec python, anguille. J'ai également écrit le processus de fermeture d'OpenGL en toute sécurité. Je le fais avec python, donc vous n'en aurez peut-être pas besoin. Je ne suis pas sûr de cela. Je suis trop enthousiaste et je ne pense pas que quiconque le verra, mais cela sert aussi de mémorandum à moi.

Recommended Posts

Afficher pyopengl dans le navigateur (python + anguille)
Afficher une liste d'alphabets en Python 3
Afficher Python 3 dans le navigateur avec MAMP
Prendre une capture d'écran en Python
Créer une fonction en Python
Créer un dictionnaire en Python
Créer un bookmarklet en Python
Afficher un histogramme des valeurs de luminosité de l'image en python
Dessinez un cœur en Python
Construction de l'environnement VScode (sur Mac) et affichage des graphiques en Python (@ browser)
Probablement dans un serpent Nishiki (Titre original: Peut-être en Python)
Ecrire une dichotomie en Python
[python] Gérer les fonctions dans une liste
Appuyez sur une commande en Python (Windows)
Dessinez une matrice de diagramme de dispersion avec python
ABC166 en Python A ~ C problème
Ecrire des algorithmes A * (A-star) en Python
Créer un fichier binaire en Python
Affichage de la forme d'onde audio en Python
Afficher des caractères comme AA en python
Résoudre ABC036 A ~ C avec Python
Ecrire le plugin vim en Python
Écrire une recherche de priorité en profondeur en Python
Implémentation d'un algorithme simple en Python 2
Résoudre ABC037 A ~ C avec Python
Exécutez un algorithme simple en Python
Dessinez un diagramme CNN en Python
Créer une chaîne aléatoire en Python
Lors de l'écriture d'un programme en Python
Générer une collection de première classe en Python
Afficher les formules de notation LaTeX en Python, matplotlib
[Python, Julia] Affichage 3D dans la bibliothèque Jupyter-Mayavi
Livre en spirale en Python! Python avec un livre en spirale! (Chapitre 14 ~)
Résoudre ABC175 A, B, C avec Python
Utiliser l'impression dans l'expression lambda Python2
Un client HTTP simple implémenté en Python
Faites une visite Euler non récursive en Python
Django ~ Affichons-le sur le navigateur ~
J'ai fait un programme de gestion de la paie en Python!
Précautions lors du décapage d'une fonction en python
Ecrire le test dans la docstring python
Afficher les diagrammes matplotlib dans une application Web
Essayez d'envoyer un paquet SYN en Python
Essayez de dessiner une animation simple en Python
Créer une application GUI simple en Python
Ecrire une courte définition de propriété en Python
Dessiner un cœur avec Python Partie 2 (SymPy Edition)
[Python] [Windows] Faites une capture d'écran avec Python
Exécuter l'interpréteur Python dans le script
Comment obtenir stacktrace en python
Comment afficher la table quatre-vingt-dix-neuf en python
Ecrire un programme de chiffrement Caesar en Python
Hash en Perl est un dictionnaire en Python
Scraping de sites Web à l'aide de JavaScript en Python
Ecrire une méthode de cupidité simple en Python
Résoudre ABC165 A, B, D avec Python
[GPS] Créer un fichier kml avec Python
Ecrire un plugin Vim simple en Python 3