WebGL + SDL + Emscripten

最終的に、SDL 1 と Emscripten を使用して、Mika を WebGL に移植しました。

次に、JavaScript でのビルドを正常に完了するためにコードの何を変更する必要があるかを説明します。

<オル>

  • SDL 2 の代わりに SDL 1 を使用します。現時点では、emscripten 用の SDL 2 ポートがありますが、emscripten に組み込まれている SDL 1 を使用する方が適切であることがわかりました。コンテキストはウィンドウ内では初期化されませんが、SDL_SetVideoMode と SDL_OPENGL フラグを使用して初期化されます。バッファは SDL_GL_SwapBuffers() コマンドを使用して描画されます
  • JavaScript のループ方法による –レンダリングは別の関数に配置され、その定期的な呼び出しは emscripten_set_main_loop
  • 関数を使用して行われます。

  • アセンブリはキー “-s FULL_ES2=1“ を使用して実行する必要もあります
  • assimp ライブラリを放棄し、ファイル システムからモデルをロードし、ディスクからテクスチャをロードする必要がありました。必要なバッファはすべてデスクトップ バージョンにロードされ、emscripten を使用してアセンブリ用の C ヘッダー ファイルに挿入されました。
  • コード:
    https://github.com/demensdeum/OpenGLES3-Experiments/tree/master/9-sdl-gles-obj-textured-assimp-miku-webgl/mikuWebGL

    記事:
    http://blog.scottlogic.com/2014/03/12/native-code-emscripten-webgl-simmer-gently.html
    https://kripken.github.io/emscripten-site/docs/porting/multimedia_and_graphics/OpenGL-support.html

    モデル:
    https://sketchfab.com/models/7310aaeb8370428e966bdcff414273e7

    ミクしかいない

    OpenGL ES とコードを使用して FSGL ライブラリを操作した結果:

    次に、すべてがどのようにプログラムされ、 さまざまな興味深い問題が解決されたかを説明します。

    最初に、前の投稿で書いたように、OpenGL ES コンテキストを初期化します。さらに、コードのレンダリングと簡単な説明のみを考慮します。

    マトリックスがあなたを見ています

    ビデオ内のこのミクの図は三角形で構成されています。 OpenGL で三角形を描くには、座標 x、y、z で 3 つの点を指定する必要があります。 OpenGL コンテキストの 2D 座標で。
    3D 座標を含む図形を描画する必要があるため、射影行列を使用する必要があります。また、モデルを回転したり、ズームインしたり、その他の操作を行う必要もあります。この目的のためにモデル マトリックスが使用されます。実際、OpenGL にはカメラの概念がありません。オブジェクトは静的なカメラの周りを回転します。このために、ビュー マトリックスが使用されます。

    OpenGL ES の実装を簡素化するため –行列データは含まれません。 GLM など、不足している機能を追加するライブラリを使用できます。

    シェーダー

    開発者があらゆる方法であらゆるものを描画できるようにするには、OpenGL ES は頂点シェーダーとフラグメント シェーダーを実装する必要があります。頂点シェーダーは、レンダリング座標を入力として受け取り、行列を使用して変換を実行し、その座標を gl_Position に渡す必要があります。フラグメントまたはピクセル シェーダ –すでにカラー/テクスチャを描画し、オーバーレイを適用しています。

    GLSL でシェーダーを作成しました。現在の実装では、シェーダはメイン アプリケーション コードに C-string として直接組み込まれています。

    バッファ

    頂点バッファには頂点 (頂点) の座標が含まれており、このバッファにはテクスチャリング用の座標やシェーダに必要なその他のデータも含まれています。頂点バッファーを生成した後、ポインターを頂点シェーダーのデータにバインドする必要があります。これは、glVertexAttribPointer コマンドを使用して行われます。このコマンドでは、要素の数、データの先頭へのポインター、およびバッファーをトラバースするために使用されるステップ サイズを指定する必要があります。私の実装では、ピクセル シェーダの頂点座標とテクスチャ座標のバインドが行われます。ただし、フラグメント シェーダーへのデータ (テクスチャ座標) の転送は頂点シェーダーを通じて実行されることは言うまでもありません。これを実現するために、 座標は変数を使用して宣言されます。

    これにより、OpenGL は三角形の点をどの順序で描画するかを認識できるようになります –インデックスバッファ(インデックス)が必要になります。インデックス バッファには、そのような 3 つのインデックスを使用して配列内の頂点番号が含まれており、三角形が取得されます。

    テクスチャ

    まず、OpenGL 用のテクスチャをロード/生成する必要があります。このために、テクスチャは bmp ファイルからロードされる SDL_LoadBMP を使用しました。ただし、24 ビット BMP のみが適切であり、その色は通常の RGB 順序ではなく BGR で保存されることに注意してください。つまり、ロード後に赤チャンネルを青チャンネルに置き換える必要があります
    。テクスチャ座標は の形式で指定します。 UV、つまり、2 つの座標を転送するだけで済みます。テクスチャの出力はフラグメント シェーダーで行われます。これを行うには、テクスチャをフラグメント シェーダにバインドする必要があります。

    余分なものは何もありません

    私たちの指示によれば、OpenGL は 2D を通じて 3D を描画するため、–次に深度を実装し、非表示の三角形を選択します –カリングと深度バッファ (Z バッファ) を使用する必要があります。私の実装では、glEnable(GL_DEPTH_TEST); という 2 つのコマンドを使用して、深度バッファの手動生成を回避できました。および選択 glEnable(GL_CULL_FACE);
    また、射影行列の近平面がゼロより大きいことも必ず確認してください。ヌル近傍平面を使用した深さのチェックは機能しません。

    レンダリング

    頂点バッファ、インデックス バッファを意識的なもの (ミク モデルなど) で埋めるには、このモデルをロードする必要があります。このために、assimp ライブラリを使用しました。ミクは Wavefront OBJ 形式ファイルに配置され、assimp を使用してロードされ、assimp から頂点およびインデックス バッファーへのデータ変換が実装されました。

    レンダリングはいくつかの段階で行われます:

    <オル>

  • モデル行列の回転を使用してミクを回転します
  • 画面と深度バッファをクリアする
  • glDrawElements コマンドを使用して三角形を描画します。
  • 次のステージ – Emscripten を使用した WebGL でのレンダリングの実装。

    ソースコード:
    https://github.com/demensdeum/OpenGLES3-Experiments/tree/master/8-sdl-gles-obj-textured-assimp-miku
    モデル:
    https://sketchfab.com/models/7310aaeb8370428e966bdcff414273e7

     

    投影してみよう

    赤いティーポットを 3D で描いたので、その作り方を簡単に説明するのが私の義務だと考えています。

    最新の OpenGL は 3D を描画せず、2D 画面座標で三角形や点などを描画するだけです。
    OpenGL を使用して少なくとも何かを出力するには、頂点バッファを提供し、頂点シェーダーを作成し、必要なすべての行列 (投影、モデル、ビュー) を頂点シェーダーに追加し、 すべての入力データを関連付ける必要があります。シェーダでは、OpenGL でメソッド レンダリングを呼び出します。シンプルに見えますか?


    頂点バッファとは何ですか?描画する座標(x,y,z)のリスト
    頂点シェーダーは GPU にどの座標を描画するかを指示します。
    ピクセル シェーダーは何を描画するか (色、テクスチャ、ブレンディングなど) を指示します。
    マトリックスは、3D 座標をレンダリングできる 2D OpenGL 座標に変換します。

    次の記事では、コード例と結果を示します。

    SDL2 – OpenGL ES

    I love Panda3D game engine. But right now this engine is very hard to compile and debug on Microsoft Windows operation system. So as I said some time ago, I begin to develop my own graphics library. Right now it’s based on OpenGL ES and SDL2.
    In this article I am going to tell how to initialize OpenGL ES context and how SDL2 helps in this task. We are going to show nothing.

    King Nothing

    First of all you need to install OpenGL ES3 – GLES 3 libraries. This operation is platform dependant, for Ubuntu Linux you can just type sudo apt-get install libgles2-mesa-dev. To work with OpenGL you need to initialize OpenGL context. There is many ways to do that, by using one of libraries – SDL2, GLFW, GLFM etc. Actually there is no one right way to initialize OpenGL context, but I chose SDL2 because it’s cross-platform solution, code will look same for Windows/*nix/HTML5/iOS/Android/etc.

    To install sdl2 on Ubuntu use this command sudo apt-get install libsdl2-dev

    So here is OpenGL context initialization code with SDL2:

        SDL_Window *window = SDL_CreateWindow(
                "SDL2 - OGLES",
                SDL_WINDOWPOS_UNDEFINED,
                SDL_WINDOWPOS_UNDEFINED,
                640,
                480,
                SDL_WINDOW_OPENGL
                );
    	    
    
        SDL_GLContext glContext = SDL_GL_CreateContext(window);
    

    After that, you can use any OpenGL calls in that context.

    Here is example code for this article:
    https://github.com/demensdeum/OpenGLES3-Experiments/tree/master/3sdl-gles
    https://github.com/demensdeum/OpenGLES3-Experiments/blob/master/3sdl-gles/sdlgles.cpp

    You can build and test it with command cmake . && make && ./SDLGles

    Russian Quantum Hack and Number Generator

    [Translation may be, some day]

    Эта заметка увеличит длину вашего резюме на 5 см!

    Без лишних слов о крутости квантовых компьютеров и всего такого, сегодня я покажу как сделать генератор чисел на реальном квантовом процессоре IBM.
    Для этого мы будем использовать всего один кубит, фреймворк для разработки квантового ПО для python – ProjectQ, и 16 кубитовый процессор от IBM, онлайн доступ к которому открыт любому желающему по программе IBM Quantum Experience.

    Установка ProjectQ

    Для начала у вас должен быть Linux, Python и pip. Какие либо инструкции по установке этих базовых вещей приводить бесполезно, т.к. в любом случае инструкции устареют через неделю, поэтому просто найдите гайд по установке на официальном сайте. Далее устанавливаем ProjectQ, гайд по установке приведен в документации. На данный момент все свелось к установке пакета ProjectQ через pip, одной командой: python -m pip install –user projectq

    Ставим кубит в суперпозицию

    Создаем файл quantumNumberGenerator.py и берем пример генератора бинарного числа из документации ProjectQ, просто добавляем в него цикл на 32 шага, собираем бинарную строку и переводим в 32-битное число:

    import projectq.setups.ibm
    from projectq.ops import H, Measure
    from projectq import MainEngine
    from projectq.backends import IBMBackend
    
    binaryString = ""
    
    eng = MainEngine()
    
    for i in range(1, 33):
    
     qubit = eng.allocate_qubit()
    
     H | qubit
    
     Measure | qubit
    
     eng.flush()
    
     binaryString = binaryString + str(int(qubit))
    
     print("Step " + str(i))
    
    number = int(binaryString, 2)
    
    print("\n--- Quantum 32-Bit Number Generator by demensdeum@gmail.com (2017) ---\n")
    print("Binary: " + binaryString)
    print("Number: " + str(number))
    print("\n---")
    

    Запускаем и получаем число из квантового симулятора с помощью команды python quantumNumberGenerator.py

    Незнаю как вы, но я получил вывод и число 3974719468:

    --- Quantum 32-Bit Number Generator by demensdeum@gmail.com (2017) ---
    
    Binary: 11101100111010010110011111101100
    Number: 3974719468
    
    ---
    

    Хорошо, теперь мы запустим наш генератор на реальном квантовом процессоре IBM.

    Хакаем IBM

    Проходим регистрацию на сайте IBM Quantum Experience, подтверждаем email, в итоге должен остаться email и пароль для доступа.
    Далее включаем айбиэмовский движок, меняем строку eng = MainEngine() -> eng = MainEngine(IBMBackend())
    В теории после этого вы запускаете код снова и теперь он работает на реальном квантовом процессоре, используя один кубит. Однако после запуска вам придется 32 раза набрать свой email и пароль при каждой аллокации реального кубита. Обойти это можно прописав свой email и пароль прямо в библиотеки ProjectQ.

    Заходим в папку где лежит фреймворк ProjectQ, ищем файл с помощью grep по строке IBM QE user (e-mail).
    В итоге я исправил строки в файле projectq/backends/_ibm/_ibm_http_client.py:

    email = input_fun('IBM QE user (e-mail) > ') -> email = "quantumPsycho@aport.ru"
    
    password = getpass.getpass(prompt='IBM QE password > ') -> password = "ilovequbitsandicannotlie"
    

    Напишите свой email и password со-но.

    После этого IBM будет отправлять результаты работы с кубитом онлайн прямо в ваш скрипт, процесс генерации занимает около 20 секунд.

    Возможно в дальнейшем я доберусь до работы квантового регистра, и возможно будет туториал, но это не обязательно.
    Да прибудет с вами запутанность.

    Статья на похожую тему:
    Introducing the world’s first game for a quantum computer

    Porting SDL C++ Game to HTML5 (Emscripten)

    [Translation may be some day]

    За последний год я написал простейший движок Flame Steel Engine и набор классов для игровой разработки Flame Steel Engine Game Toolkit. В данной статье я опишу как производил портирование движка и SDL игры Bad Robots на HTML 5, с использованием компилятора Emscripten.

    Установка Hello World – Emscripten

    Для начала нужно установить Emscripten. Простейшим вариантом оказалось использование скрипта emsdk для Linux. На официальном сайте данный тип установки называется как “Portable Emscripten SDK for Linux and OS X“. Внутри архива есть инструкция по установке с использованием скрипта. Я производил установку в директорию ~/emsdk/emsdk_portable.

    После установки emscripten нужно проверить корректность работы компилятора, для этого создаем простейший hello_world.cpp и собираем его в hello_world.html с помощью команд:

    source ~/emsdk/emsdk_portable/emsdk_env.sh
    emcc hello_world.cpp -o hello_world.html

    После компиляции в папке появится hello_world.html и вспомогательные файлы, откройте его в лучшем браузере Firefox, проверьте что все работает корректно.

    Портирование кода игры

    В javascript нежелательно вызывать бесконечный цикл – это приводит к зависанию браузера. На данный момент корректная стратегия – запрашивать один шаг цикла у браузера с помощью вызова window.requestAnimationFrame(callback)

    В Emscripten данное обстоятельство решено с помощью вызова:

    emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop);

    Таким образом, нужно изменить код игры для корректного вызова метода emscripten. Для этого я сделал глобальный метод GLOBAL_fsegt_emscripten_gameLoop, в котором вызываю шаг цикла игрового контроллера. Главный игровой контроллер также вынесен в глобальную видимость:

    #ifdef __EMSCRIPTEN__
    
    void GLOBAL_fsegt_emscripten_gameLoop() {
    
    GLOBAL_fsegt_emscripten_gameController->gameLoop();
    
    }
    #endif
    

    Также для обработки специфических для Emscripten моментов, нужно использовать макрос __EMSCRIPTEN__.

    Ресурсы и оптимизация

    Emscripten поддерживает ресурсы и сборку с оптимизацией.

    Для добавления изображений, музыки и прочего, положите все файлы в одну папку, например data. Далее в скрипт сборки добавьте:

    emcc <файлы для сборки> –use-preload-plugins –preload-file data

    Флаг –use-preload-plugins включает красивый прелоадер в углу экрана, –preload-file добавляет указанный ресурс в файл <имя проекта>.data
    Код постоянно останавливался с ошибками доступа к ресурсам, пока я не включил оба этих флага. Также стоит заметить что для корректного доступа к ресурсам, желательно запускать игру на https (возможно и http) сервере, или отключить защиту локального доступа к файлам в вашем браузере.

    Для включения оптимизации добавьте флаги:

    -s TOTAL_MEMORY=67108864 -O3 -ffast-math

    TOTAL_MEMORY – оперативная память в байтах(?) необходимая для корректной работы игры. Вы можете использовать флаг для динамического выделения памяти, но тогда часть оптимизаций работать не будет.

    Производительность

    Код javascript из C++ работает гораздо медленнее, даже со включенными оптимизациями. Поэтому если ваша цель это разработка для HTML5, то приготовьтесь к ручной оптимизации алгоритмов игры, паралелльному тестированию, также к написанию javascript кода вручную в особо узких местах. Для написания javascript кода используется макрос EM_ASM. Во время реализации рейкастера на emscripten, мне удалось добиться повышения fps с 2-4 до 30 с помощью прямого использования методов canvas.drawImage, в обход обертки SDL->Canvas, что почти приравнялось к написанию всего на javascript.

    Поддержка SDL

    На данный момент почти не работает SDL_TTF, поэтому отрисовка шрифта для Game Score в BadRobots очень проста. SDL_Image, SDL_Mixer работают корректно, в mixer я проверил только проигрывание музыки.

    Исходный код Flame Steel Engine, Flame Steel Engine Game Toolkit, игры Bad Robots:

    https://github.com/demensdeum/BadRobots
    https://github.com/demensdeum/FlameSteelEngine
    https://github.com/demensdeum/FlameSteelEngineGameToolkit

    Статья на эту тему:

    https://hacks.mozilla.org/2012/04/porting-me-my-shadow-to-the-web-c-to-javascriptcanvas-via-emscripten/

    チュートリアル: Android でゲームを作成する。私たちは地球をねじります。ラジャワリ語

    初めに神は天と地を創造されました。

    これは、Android 用のゲームを作成する 2 番目のビデオです。地球を動かそう
    !ご質問がある場合、またはこのコースに追加したい場合は、私までご連絡ください。
    記事に基づくビデオRajawali Basic Setup &スフィア (Maven):
    http://www.clintonmedbery.com/basic-rajawali3d-tutorial-for-android/

    ラジャワリ エンジン: https://github.com/Rajawali/Rajawali

    計画、コマンド、リンク:
    1. VirtualBox ゲストの追加機能

    をインストールします。

    sudo apt-get install dkmssudo apt-get install linux-headers-$(uname -r)

    2. Rajawali ライブラリをプロジェクトに追加
    ファイルbuild.gradle (プロジェクト: Demon’s Cave)
    mavenCentral() を追加します< /span>buildscript/repositories
    セクションへ
    maven { url< を追加します/span> “https://oss.sonatype.org/content/repositories/snapshots/” } すべてのプロジェクト/リポジトリ セクション

    ファイルbuild.gradle (モジュール: app)
    コンパイル ‘org.rajawali3d:rajawali:1.0.306-SNAPSHOT@aar& を追加します。 #8217; 依存関係
    セクションへ

    3. レンダラクラスを作成し、シーンを初期化し、球を追加して回転させます。
    Renderer.java クラスのソース コード:
    https://github.com/clintonmedbery/RajawaliBasicProject/blob/master/app/src/main/java/com/clintonmedbery/rajawalibasicproject/Renderer.java

    4. Renderer クラスを MainActivity に追加します
    ソースコード MainActivity.java:
    https://github.com/clintonmedbery/RajawaliBasicProject/blob/master/app/src/main/java/com/clintonmedbery/rajawalibasicproject/MainActivity.java

    地面のテクスチャ:
    http://www.clintonmedbery.com/wp-content/uploads/2015/04/earthtruecolor_nasa_big.jpg

    チュートリアル: Android でのゲームの作成

    ‘学習は光であり、無知は闇

    Demon’s Cave は間もなく Android に登場します。
    開発プロセスに興味を持っている人がたくさんいるので、Android へのゲームの移植に関するコースの録画を開始しました。
    ご質問がある場合、またはこのコースに追加したい場合は、私までご連絡ください。
    他の言語の字幕を追加することもできます: http://www.youtube.com/ timedtext_video?ref=share&v=rx7NYkAJB2I

    計画、コマンド、リンク:
    1. VirtualBox のインストール https://www.virtualbox.org/wiki/Downloads
    2. Xubuntu のインストール http://xubuntu.org/getxubuntu/
    3. Oracle Java 7 のインストール

    sudo add-apt-repository ppa:webupd8team/javasudo apt-get アップデートsudo apt-get install oracle-java7-installer

    4. 32 ビット ライブラリのインストール

    sudo apt-get install lib32ncurses5 lib32stdc++6 zlib1g:i386

    5. Chromium のインストール

    sudo apt-get install chrome-browser

    6. Android Studio のインストール http://developer.android.com/sdk/index.html< /p>