如果给定的"HDC"(设备上下文)已经存在DirectX上下文,则"wglCreateContext"会安全失败吗? [英] Will `wglCreateContext` fail safely if a DirectX context already exists for the given `HDC` (device context)

查看:85
本文介绍了如果给定的"HDC"(设备上下文)已经存在DirectX上下文,则"wglCreateContext"会安全失败吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为跨平台,内存安全的API做出贡献,以在Rust中创建和使用OpenGL上下文,称为

I'm attempting to contribute to a cross-platform, memory-safe API for creating and using OpenGL contexts in Rust called glutin. There is an effort to redesign the API in a way that will allow users to create a GL context for a pre-existing window.

引起关注的一个问题是,如果用户尝试为具有预先存在的DirectX上下文的窗口创建GL上下文,则这可能不是内存安全的.

One of the concerns raised was that this might not be memory safe if a user attempts to create a GL context for a window that has a pre-existing DirectX context.

c0> 建议它在失败时将返回NULL,但是没有详细说明可能是什么原因引起的.

The documentation for wglCreateContext suggests that it will return NULL upon failure, however it does not go into detail about what conditions might cause this.

如果给定HDC的DirectX上下文(设备上下文)已经存在,wglCreateContext是否会安全失败(通过返回NULL)?还是这种情况下的行为是不确定的?

Will wglCreateContext fail safely (by returning NULL) if a DirectX context already exists for the given HDC (device context)? Or is the behaviour in this situation undefined?

我无法访问具有OpenGL支持的Windows机器,因此无法自己直接测试.

I do not have access to a Windows machine with OpenGL support and am unable to test this directly myself.

推荐答案

我在这里看到的真正问题是,wglCreateContext可能由于任何原因而失败,因此您必须能够解决该问题.

The real issue I see here is, that wglCreateContext may fail for any reason, and you have to be able to deal with that.

话虽如此,您表达问题的方式却使人对OpenGL上下文,设备上下文和窗口之间的关系产生了根本性的误解.用三个简单的词来表示:没有!

That being said, the way you formulated your question reeks of a fundamental misunderstanding between the relationship between OpenGL contexts, device contexts and windows. To put in in three simple words: There is none!

好的,请澄清一下.这是怎么回事?如果不相关,为什么wglCreateContext有一个HDC参数?

Okay, that begs for clarification. What's the deal here? Why is there a HDC parameter to wglCreateContext if these are not related?

所有这些都归结为像素格式(或帧缓冲区配置).您可以在屏幕上看到的窗口是内存块的直接1:1表示.此内存块具有特定的像素格式.但是,只要使用抽象的绘制方法(如GDI),所使用的精确像素格式就无关紧要,并且图形系统可以在认为合适的情况下以静默方式切换像素格式.在漫长的争执中,当图形内存不足时,这可能意味着可以节省大量资金.

It all boils down to pixel formats (or framebuffer configuration). A window as you can see it on the screen, is a direct 1:1 representation of a block of memory. This block of memory has a certain pixel format. However as long as only abstract drawing methods are used (like the GDI is), the precise pixel format being used doesn't matter and the graphics system may silently switch the pixel format as it sees fit. In times long begone, when graphics memory was scarce this could mean huge savings.

但是OpenGL假定使用特定的不变像素格式来操作帧缓冲区.因此,为了支持添加了新API,该API可以确定给定窗口的内部像素格式.但是,由于图形系统中实际上与帧缓冲区格式有关的唯一部分是绘制内容的部分,即GDI,因此帧缓冲区的配置贯穿该部分. HWND与传递消息,将输入事件与应用程序以及所有爵士乐相关联.但是与所有图形相关的是HDC.这就是为什么要通过HDC设置像素格式的原因.

However OpenGL assumes to operate of framebuffers with a specific, unchanging pixel format. So in order to support that a new API was added that allows to nail down the internal pixel format of a given window. However since the only part of the graphics system that's actually concerned with the framebuffer format is the part that draws stuff, i.e. the GDI, the framebuffer configuration happens through that part. HWNDs are related to passing around messages, associating input events to applications and all that jazz. But it's HDCs that relate to everything graphics. So that's why you set the pixel format through an HDC.

在创建OpenGL上下文时,必须为要在其上使用的图形设备配置该上下文.这又遍历了通过HDC句柄处理的GDI和数据结构.但是,一旦创建了OpenGL上下文,它就可以与 any HDC一起使用,该指的是配置了与OpenGL上下文最初创建的HDC兼容的像素格式的帧缓冲区和.它可以是同一窗口的不同HDC,也可以是完全不同的窗口的HDC.而且自从OpenGL-3.3内核以来,就可以使OpenGL上下文成为最新的,而完全不包含HDC,它完全是自包含的,可以在自管理的帧缓冲区上运行.最后但并非最不重要的一点是,可以随时更改绑定.

When creating an OpenGL context, that context has to be configured for the graphics device it's intended to be used on. And this again goes through the GDI and data structures that are addressed through HDC handles. But once an OpenGL context has been created, it can be used with any HDC that refers to a framebuffer that has a pixel format configured that is compatible to the HDC the OpenGL context was originally created with. It can be a different HDC of the same window, or it can be a HDC of an entirely different window alltogether. And ever since OpenGL-3.3 core an OpenGL context can be made current with no HDC at all, being completely self contained, operating on self managed framebuffers. And last but not least, that binding can be changed at any time.

每当不了解这一点的人实施某种OpenGL绑定或抽象包装器时,他们往往会弄错这一部分并制造出不必要的紧身直外套,这时其他人(例如我)就必须以自己的方式奋斗出来,因为抽象的工作方式是错误的构想. Qt的人犯了这个错误,GTK +的人犯了这个错误,现在看来您也是如此.您的Github项目页面上有以下代码片段:

Everytime when people, who have no clear understanding of this, implement some OpenGL binding or abstraction wrapper, they tend to get this part wrong and create unnecessarily tight straight jackets, which then other people, like me, have to fight their way out, because the way the abstraction works is ill conceived. The Qt guys made that mistake, the GTK+ guys did so, and now it seems apparently so do you. There is this code snippet on your Github project page:

let events_loop = glutin::EventsLoop::new();
let window = glutin::WindowBuilder::new()
    .with_title("Hello, world!".to_string())
    .with_dimensions(1024, 768)
    .with_vsync()
    .build(&events_loop)
    .unwrap();

unsafe {
    window.make_current()
}.unwrap();

unsafe {
    gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);

    gl::ClearColor(0.0, 1.0, 0.0, 1.0);
}

Arrrrggggh.为什么将make_currentget_proc_address方法与窗口关联?为什么?!谁想到了这个?不要这样做,它会使不得不使用这种痛苦的人们的生活痛苦和痛苦.

Arrrrggggh. Why the heck are the methods make_current and get_proc_address associated with the window? Why?! Who came up with this? Don't do this shit, it makes the life of people who have to use this miserable and painful.

您想知道这会导致什么吗?可怕的,混乱的不安全代码,确实令人作呕和肮脏的事情,以强制性地直率地禁用了现有的某些防护措施,以使它可以正常工作.就像我必须做的一件可怕的事情一样,要弄清Qt4对OpenGL如何工作的错误假设.

Do you want to know to what this leads? Horribly, messy unsafe code, that does disgusting and dirty things to forcefully and bluntly disable some of the safeguards present, just so that it can go to work. Like this horrible thing I had to do, to get Qt4's ill assumptions of how OpenGL works out of the way.

#ifndef _WIN32
#if OCTPROCESSOR_CREATE_GLWIDGET_IN_THREAD
    QGLFormat glformat(
        QGL::DirectRendering |
        QGL::DoubleBuffer |
        QGL::Rgba |
        QGL::AlphaChannel |
        QGL::DepthBuffer,
        0 );
    glformat.setProfile(QGLFormat::CompatibilityProfile);

    gl_hidden_widget = new QGLWidget(glformat);
    if( !gl_hidden_widget ) {
        qDebug() << "creating woker context failed";
        goto fail_init_glcontext;
    }
    gl_hidden_widget->moveToThread( QThread::currentThread() );
#endif

    if( !gl_hidden_widget->isValid() ) {
        qDebug() << "worker context invalid";
        goto fail_glcontext_valid;
    }

    gl_hidden_widget->makeCurrent();
#else
    if( wglu_create_pbuffer_with_glrc(
        3,3,WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
        &m_hpbuffer,
        &m_hdc,
        &m_hglrc,
        &m_share_hglrc)
    ){
        qDebug() << "failed to create worker PBuffer and OpenGL context";
        goto fail_init_glcontext;
    }
    qDebug()
        << "m_hdc" << m_hdc
        << "m_hglrc" << m_hglrc;
    if( !wglMakeCurrent(m_hdc, m_hglrc) ){
        qDebug() << "failed making OpenGL context current on PBuffer HDC";
        goto fail_glcontext_valid;
    }
#endif

这篇关于如果给定的"HDC"(设备上下文)已经存在DirectX上下文,则"wglCreateContext"会安全失败吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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