OpenGL获取设备上下文

Posted

技术标签:

【中文标题】OpenGL获取设备上下文【英文标题】:OpenGL get Device Context 【发布时间】:2017-03-23 22:26:12 【问题描述】:

我正在尝试在 Windows 上创建一个 OpenGL 应用程序。据我所知,我必须获取的第一件事是设备上下文,它必须传递给几个函数,这些函数可以选择和设置像素格式并创建渲染上下文。我使用the OpenGL wiki 大致了解我应该做什么。 我的代码是这样的:

#include <iostream>
#include <windef.h>
#include <wingdi.h>

HDC hdc;

int main() 
    hdc = wglGetCurrentDC();
    std::cout << "HDC: " << hdc << std::endl;
    return 0;

打印出来

HDC: 0

我假设设备上下文指的是物理设备,但我在某处读到它指的是任何可绘制的“表面”。在这两种情况下,我的问题是:如何获得非空 DC?或者我应该执行一组完全不同的步骤来设置整个 OpenGL 系统?

我在网上找到了很多教程,但它们都使用了 GLUT、GLEW、GLFW、X11、SDL 等库。图书馆使某些事情变得更容易,但它们通常不会执行不使用它们就不可能完成的任务。这一次,我想尝试用困难的方式做事,因此不使用任何库,只使用普通的 OpenGL。

我终于找到了a tutorial,它只使用了windows库来创建一个窗口。

【问题讨论】:

我也是这么认为的,但是这篇文章主要是关于创建一个OpenGL上下文,而我需要的上下文是一个设备上下文。文章指出:“您应该知道什么是窗口句柄 (HWND) 和设备上下文 (DC),以及如何创建它们。” 所以你的意思是代码在这种情况下不适用。我认为你可能是对的,但问题就变成了我必须如何创建一个。 对不起,你是对的;因为它是 WGL 函数,所以我把它误认为是 wglGetCurrentContext wglGetCurrentDC() 在这里无济于事。如果您查看它的文档,它“......获取与当前 OpenGL 渲染上下文相关联的设备上下文的句柄......”。这意味着您只能在创建 OpenGL 上下文之后 使用它。这一切都需要更多的代码。您必须先创建一个窗口,然后通过各种步骤来获取 DC,选择像素格式,创建 OpenGL 上下文等。超出此处的答案范围,至少对我而言……从学习开始如何仅使用 Win32 编写基本应用程序,然后添加 OpenGL 片段。 好的,有道理。谢谢。 【参考方案1】:

您没有说明您的 操作系统,但我从函数名称中假设是 Windows。问题正如 Reto Koradi 在评论中所说的那样。要设置 OpenGL,您需要这样做:

    使用有效的设备上下文获取对象的操作系统句柄

    可以是OS窗口或OS位图。如果您只有控制台应用程序,那么您需要先创建一个有效的 OS 窗口并使用它的句柄(据我所知,控制台没有 Canvas)。

    您可以使用 GLUT 来创建窗口,或者如果您的编译器 IDE 有一个窗口应用程序,您可以使用它。您还可以组合 OpenGL 和 Window 组件。 VCL 也不是问题(我多年来一直使用 OpenGL

    在 Windows 中,您可以使用CreateWindowEx,因此请在 Google 上找到它的示例...

    无论如何,您应该将句柄放在一个变量中,例如:

    HWND hwin=NULL;
    

    如果您没有使用 Windows 应用程序的经验,请使用 GLUT。否则,您将需要学习很多东西,以涵盖窗口创建、事件的消息处理和用户/应用程序交互,这对于没有指导的新手来说真的是不堪重负。

    获取该句柄的设备上下文

    HDC hdc = GetDC(hwin);
    

    设置设备上下文所需的像素格式

    PIXELFORMATDESCRIPTOR pfd;
    ZeroMemory( &pfd, sizeof( pfd ) );      // set the pixel format for the DC
    pfd.nSize = sizeof( pfd );
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 24;
    pfd.iLayerType = PFD_MAIN_PLANE;
    SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
    

    为设备上下文创建 OpenGL 渲染上下文

    HGLRC hrc = wglCreateContext(hdc);
    

    将其设置为默认 OpenGL 上下文

    wglMakeCurrent(hdc, hrc);
    

这是绝对最小值,没有任何错误检查、额外的缓冲区等。有关更多信息和实际代码,请参阅相关 QA

How to render an openGL frame in C++ builder? for oldstyle GL simple complete GL+VAO/VBO+GLSL+shaders example in C++ 新东西

您可以使用 GLUT 来完成所有这些操作。这是我通过快速搜索找到的第一个命中:

How can I set an OpenGL display (Window created by OpenGL) to maximized?

或者按照 OpenGL 教程,那里有很多...

【讨论】:

很抱歉我没有提到我的操作系统。正如您已经猜到的那样,它是窗户。至于您描述的步骤:我得到 3、4 和 5,因为它们在我使用的 wiki 文章中描述得很清楚。感谢您明确我首先必须创建一个窗口。关于使用 GLUT... GLUT 是一个库,这意味着可能还有一种方法可以在不使用它的情况下创建一个窗口? CreateWindow 或 CreateWindowEx 可能会起作用,所以我会尝试。谢谢。

以上是关于OpenGL获取设备上下文的主要内容,如果未能解决你的问题,请参考以下文章

具有多个设备(监视器)的 OpenGL 上下文

OpenGL在没有或有静态设备上下文的情况下加载纹理?

基于OpenGL三维软件开发

什么时候使用 Qt 在 opengl 中创建渲染上下文?

在 OpenGL 上下文中使用 SDL 进行 Blitting

Blender源码分析之OpenGL函数初步