如何在MacOS的NodeJS本机插件上创建OpenGL上下文? [英] How to create an OpenGL context on an NodeJS native addon on MacOS?

查看:247
本文介绍了如何在MacOS的NodeJS本机插件上创建OpenGL上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此内容的后续行动问题.

我正在尝试创建一个使用OpenGL的NodeJS本机插件.

I'm trying to create a NodeJS native addon that uses OpenGL.

我无法使用OpenGL函数,因为CGLGetCurrentContext()始终返回NULL.

I'm not able to use OpenGL functions because CGLGetCurrentContext() always returns NULL.

当尝试创建要绘制的新上下文时,CGLChoosePixelFormat始终返回错误kCGLBadConnection invalid CoreGraphics connection.

When trying to create a new context to draw into, CGLChoosePixelFormat always returns the error kCGLBadConnection invalid CoreGraphics connection.

让我烦恼的是,当我将创建OpenGL上下文的代码隔离到一个独立的CPP项目中时,它可以工作!当我在NodeJS插件中运行它时,它只会给出一个错误!

What is bugging me out is that when I isolate the code that creates the OpenGL context into a standalone CPP project, it works! It just gives an error when I run it inside the NodeJS addon!

我创建了这个NodeJS本机附加项目来举例说明我的错误: https://github.com/Psidium/node-opengl-context-error-example

I created this NodeJS native addon project to exemplify my error: https://github.com/Psidium/node-opengl-context-error-example

这是在独立项目上执行时有效的代码,在NodeJS中运行时会出错:

This is the code that works when executed on a standalone project and errors out when running inside 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属性更改为将创建我的上下文的内容(无效);
  • Using fork() to create a context in a subprocess (didn't work);
  • Changing the pixelformat attributes to something that will create my context (didn't work);

我有一个预感,这可能与Node本机插件是动态链接的库有关,或者我的OpenGL createContext函数可能未在主线程上执行(但是如果这是情况下,fork()会解决它,对吧?).

I have a hunch that it may have something to do with the fact that a Node native addon is a dynamically linked library, or maybe my OpenGL createContext function may not be executing on the main thread (but if this was the case, the fork() would have solved it, right?).

推荐答案

访问图形硬件需要额外的权限-Windows和macOS(其他用户不知道)将创建硬件加速的OpenGL上下文限制为交互式用户会话(此处的条款我可能有误).从网络上的一篇文章中:

Accessing graphics hardware requires extra permissions - Windows and macOS (don't know for others) restrict creation of hardware-accelerated OpenGL context to interactive user session (I may be wrong with the terms here). From one of articles on the web:

如果用户未登录,则CGLChoosePixelFormat将返回kCGLBadConnection

In case the user is not logged in, the CGLChoosePixelFormat will return kCGLBadConnection

互动会话理解更容易感觉;例如当您交互式登录并启动应用程序时-这是交互式会话;当流程作为服务启动时-是非交互式的.如何通过系统实际管理它需要更深入的了解.据我所知,没有简单的方法可以转义"非交互过程标志.

Interactive session is easier to feel than to understand; e.g. when you interactively login and launch application - it is interactive session; when process is started as service - it is non-interactive. How this is actually managed by system requires deeper reading. As far as I know, there is no easy way "escaping" non-interactive process flag.

NodeJS可以用作网络服务器的一部分,因此我可以预料这可能就是问题所在-它是由另一个非交互式用户作为服务启动的,或者具有其他特殊条件,使其无法使用-交互的.因此,也许有关如何使用/启动NodeJS本身的更多详细信息可能会阐明为什么代码不起作用.但是我可能希望在服务器部分使用OpenGL可能不是一个好主意(如果这是目标).尽管有可能使用软件OpenGL实现(不带kCGLPFAAccelerated标志可能会起作用).

NodeJS can be used as part of a web-server, so that I may expect that it can be exactly the problem - it is started as a service, by another non-interactive user or has other special conditions making it non-interactive. So maybe more details on how you use / start NodeJS itself might clarify why the code doesn't work. But I may expect that using OpenGL on server part might be not a good idea anyway (if this is a target); although it might be possible that software OpenGL implementation (without kCGLPFAAccelerated flag might work).

顺便说一下,NodeJS至少有两个OpenGL/WebGL扩展-您是否尝试过他们的示例以查看它们在您的环境中是以相同还是不同的方式运行的? > https://github.com/google/node-gles https://github.com/mikeseven/node-webgl

By the way, there are at least two OpenGL / WebGL extensions to NodeJS - have you tried their samples to see if they behave in the same or different way in your environment? https://github.com/google/node-gles https://github.com/mikeseven/node-webgl

这篇关于如何在MacOS的NodeJS本机插件上创建OpenGL上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆