Как создать контекст OpenGL для NodeJS собственного дополнения в MacOS? - PullRequest
1 голос
/ 05 апреля 2020

Продолжение для этого вопроса.

Я пытаюсь создать NodeJS собственный аддон, использующий OpenGL.

Я не могу используйте функции OpenGL, потому что CGLGetCurrentContext() всегда возвращает NULL.

При попытке создать новый контекст для рисования, CGLChoosePixelFormat всегда возвращает ошибку kCGLBadConnection invalid CoreGraphics connection.

Что меня беспокоит, так это то, что когда я изолирую код, который создает контекст OpenGL, в отдельный CPP проект, он работает! Он просто выдает ошибку, когда я запускаю его внутри NodeJS аддона!

Я создал этот NodeJS собственный проект аддона, чтобы проиллюстрировать мою ошибку: https://github.com/Psidium/node-opengl-context-error-example

Этот код работает при выполнении в автономном проекте и выдает ошибки при запуске внутри NodeJS:

//
//  main.cpp
//  test_cli
//
//  Created by Borges, Gabriel on 4/3/20.
//  Copyright © 2020 Psidium. All rights reserved.
//

#include <iostream>
#include <OpenGL/OpenGL.h>

int main(int argc, const char * argv[]) {
    std::cout << "Context before creating it: " << CGLGetCurrentContext() << "\n";
       CGLContextObj context;
    CGLPixelFormatAttribute attributes[2] = {
            kCGLPFAAccelerated,   // no software rendering
            (CGLPixelFormatAttribute) 0
    };
    CGLPixelFormatObj pix;
    CGLError errorCode;
    GLint num; // stores the number of possible pixel formats
    errorCode = CGLChoosePixelFormat( attributes, &pix, &num );
    if (errorCode > 0) {
      std::cout << ": Error returned by choosePixelFormat: " << errorCode << "\n";
        return 10;
    }

    errorCode = CGLCreateContext( pix, NULL, &context );
    if (errorCode > 0) {
      std::cout << ": Error returned by CGLCreateContext: " << errorCode << "\n";
      return 10 ;
    }

    CGLDestroyPixelFormat( pix );

    errorCode = CGLSetCurrentContext( context );
    if (errorCode > 0) {
      std::cout << "Error returned by CGLSetCurrentContext: " << errorCode << "\n";
      return 10;
    }
    std::cout << "Context after being created is: " << CGLGetCurrentContext() << "\n";
    return 0;
}

Я уже пробовал:

  • Использование fork() для создать контекст в подпроцессе (не работает);
  • Изменение атрибутов pixelformat на что-то, что создаст мой контекст (не работает);

У меня есть догадка, что это может иметь какое-то отношение к тому факту, что собственный аддон Node является динамически связанной библиотекой, или, возможно, моя функция OpenGL createContext может не выполняться в главном потоке (но если это так, то fork() решил бы это, верно?).

1 Ответ

0 голосов
/ 07 апреля 2020

Для доступа к графическому оборудованию требуются дополнительные разрешения - Windows и macOS (не знаю для других) ограничивают создание аппаратно-ускоренного контекста OpenGL до интерактивного сеанса пользователя (я могу ошибаться с условиями здесь ). Из одной из статей в Интернете:

Если пользователь не вошел в систему, CGLChoosePixelFormat вернет kCGLBadConnection

Интерактивный сеанс проще почувствовать , чем понять ; например, когда вы входите в систему и запускаете приложение в интерактивном режиме - это интерактивный сеанс; когда процесс запускается как сервис - он неинтерактивный. Как это на самом деле управляется системой, требует более глубокого прочтения. Насколько я знаю, не существует простого способа "избежать" неинтерактивного флага процесса.

NodeJS можно использовать как часть веб-сервера, так что я могу ожидать, что он может быть точно проблема - он запускается как сервис, другим неинтерактивным пользователем или имеет другие особые условия, делающие его неинтерактивным. Так что, возможно, более подробная информация о том, как вы используете / start NodeJS, сама может объяснить, почему код не работает. Но я могу ожидать, что использование OpenGL на серверной части может быть не очень хорошей идеей (если это цель); хотя возможно, что программная реализация OpenGL (без флага kCGLPFAAccelerated может работать).

Кстати, есть по крайней мере два расширения OpenGL / WebGL для NodeJS - вы пробовали их примеры, чтобы увидеть если они ведут себя одинаково или по-другому в вашей среде? https://github.com/google/node-gles https://github.com/mikeseven/node-webgl

...