Как создать контекст 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