简体   繁体   English

如何在C ++程序中使用gl.h?

[英]How do I use gl.h in a C++ program?

I am trying to understand why this program will compile in C but not C++ and why extern "C" { } doesn't seem to help. 我试图理解为什么该程序将使用C而不是C ++进行编译,以及为什么extern "C" { }似乎无济于事。

This short program doesn't actually do anything, but shows by example that there is a difference in the compilation when it is C vs C++. 这个简短的程序实际上并没有执行任何操作,而是通过示例显示了C与C ++的编译存在差异。

    #include <GL/gl.h>
    int main() {
        glBegin(GL_POLYGON);
        glUseProgram(0);
        glEnd();
        return 0;
    }

When you save that as ex.c and compile it with gcc ex.c -lGL -o ex it compiles and links as expected. 将其另存为ex.c并使用gcc ex.c -lGL -o ex编译时, gcc ex.c -lGL -o ex会按预期进行编译和链接。

When you save it as ex.cpp and compile it with gcc ex.cpp -lGL -o ex you get a compiler error: 将其另存为ex.cpp并使用gcc ex.cpp -lGL -o ex进行编译时,会出现编译器错误:

error: ‘glUseProgram’ was not declared in this scope

Note that it does not complain about glBegin, glEnd, or GL_POLYGON. 请注意,它不会抱怨glBegin,glEnd或GL_POLYGON。 In fact, you can comment out the glUseProgram line and it compiles just fine as a cpp program. 实际上,您可以注释掉glUseProgram行,它可以作为cpp程序进行编译。

Now, why can't I wrap the program in extern "C" like so: 现在,为什么我不能像这样将程序包装在extern "C"

    extern "C" {
        #include <GL/gl.h>
        int main() {
            glBegin(GL_POLYGON);
            glUseProgram(0);
            glEnd();
            return 0;
        }
    }

Doing so still leads to the same compiler error. 这样做仍然会导致相同的编译器错误。 My understanding of extern "C" is incomplete. 我对extern "C"理解不完整。

Ultimately I need to understand what is wrong because I am trying to write a C++ program that uses many of the GL functions that apparently won't compile in C++. 最终,我需要了解问题所在,因为我试图编写一个使用许多GL函数的C ++程序,这些函数显然不会在C ++中编译。

How do I use gl.h in a C++ program? 如何在C ++程序中使用gl.h?


To address a few of the comments: I am using Mesa on X11. 要解决一些评论:我在X11上使用Mesa。 glUseProgram definition is in glext.h which is included via gl.h. glUseProgram定义在glext.h中,该定义包含在gl.h中。 I have already written a C++ program using OpenGL (actually GLES) on a raspi. 我已经在raspi上使用OpenGL(实际上是GLES)编写了一个C ++程序。 converting it to X11 is proving to be a non-trivial matter. 事实证明将其转换为X11并非易事。

As I've commented, placing #define GL_GLEXT_PROTOTYPES before the include directive solves your problem. 正如我已评论过的那样,将#define GL_GLEXT_PROTOTYPES放在include指令之前即可解决您的问题。

See the OpenGL ABI for Linux : 请参阅适用于Linux的OpenGL ABI

Normally, prototypes are present in the header files, but are not visible due to conditional compilation. 通常,原型存在于头文件中,但由于条件编译而看不到。 To define prototypes as well as typedefs, the application must #define GL_GLEXT_PROTOTYPES prior to including gl.h or glx.h. 要定义原型和typedef,应用程序必须在包含gl.h或glx.h之前#define GL_GLEXT_PROTOTYPES。 (Note: consistency suggests using GLX_GLXEXT_PROTOTYPES for glxext.h - TBD). (注意:一致性建议对glxext.h-TBD使用GLX_GLXEXT_PROTOTYPES)。

This is usually done by something like GLUT or GLEW in their header files, so if you're working with them it's typically not needed to defined the macro yourself -- however be sure to include their headers before the GL/gl.h 这通常是通过在其头文件中使用GLUTGLEW类的方式完成的,因此,如果您使用它们,通常不需要自己定义宏-但是请确保在GL/gl.h 之前包括其头。

EDITED: The reason why glBegin works fine while there's problem with glUseProgram is that glBegin comes with the very first draft of OpenGL while glUseProgram had been an extension and hasn't get introduced until OpenGL 2.0. 编辑: glBeginglUseProgram存在问题时glUseProgram正常工作的原因是glBegin随OpenGL的第一稿而来,而glUseProgram是扩展,直到OpenGL 2.0才引入。

EDITED: 编辑:
Let's be more specific: why it works with C but not C++? 让我们更具体一点:为什么它可以与C一起使用,但不能与C ++一起使用? First of all, there is no GL_GLEXT_PROTOTYPES defined in neither C or C++ version. 首先,在C或C ++版本中都没有定义GL_GLEXT_PROTOTYPES You could test it with simply some code like this: 您可以使用以下一些代码进行测试:

#ifdef GL_GLEXT_PROTOTYPES
puts("macro detected");
#endif

The reason, however, is in C it's allowed that a symbol of function could get no definition at all (which would be assumed as all its parameters are int and also returns an int), while in C++ it's not allowed. 但是,原因是在C语言中,允许函数符号完全不定义(可以假定其所有参数均为int并且还返回int),而在C ++中则不允许。

The quickest way to get it working, is to define GL_GLEXT_PROTOTYPES before the gl.h include : 使它工作最快的方法是在gl.h include之前定义GL_GLEXT_PROTOTYPES

#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>

in order to expose the function prototypes. 为了公开功能原型。

The reason it still works in C without the prototypes (function declaratons), is because C is not as strict as C++ about needing the function declaration for a called function (it'll implicitly assume a int fun() function declaration). 它在没有原型(函数声明)的情况下仍可以在C中工作的原因是,因为C在调用函数的函数声明方面不如C ++严格(它将隐式地假定为int fun()函数声明)。

The first thing you need to do, is check if you have the various gl header files. 您需要做的第一件事是检查您是否具有各种gl头文件。 If you have them already, check if you have the needed native files (.dll) and be sure that you load them into your program/project. 如果已经有了它们,请检查是否具有所需的本机文件(.dll),并确保将它们加载到程序/项目中。

Get GLEW (OpenGL Extension Wrangler Library) 获取GLEW(OpenGL扩展牧马人库)

For your own sake get something like GLEW . 为了您自己,请购买GLEW之类的东西 Why? 为什么? because by default all the GL function aren't called glUseProgram and such. 因为默认情况下,所有GL函数都不会称为glUseProgram类。 By default on my computer (Windows7) glUseProgram() is actually called PFNGLUSEPROGRAMPROC . 默认情况下,在我的计算机(Windows7)上, glUseProgram()实际上称为PFNGLUSEPROGRAMPROC

Thereby to get those "ugly" things replaced by the more readable once, simply get GLEW. 从而使那些“丑陋”的东西被更易读的东西取代,只需获取GLEW。

You could also simply #define all those "ugly" things away, though that will be A LOT OF WORK. 您也可以简单地#define所有这些“丑陋”的东西,尽管那将是很多工作。 So again it would be easier to get something like GLEW . 所以再次得到像GLEW这样的东西会更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM