Как создать контекст OpenGL в собственном аддоне NodeJS на MacOS?

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

Я пытаюсь создать собственный аддон 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 ответ

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

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

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

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

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

Другие вопросы по тегам