1.1什么是OpenGL

作者: 忘仙 | 来源:发表于2016-08-24 10:15 被阅读1692次

    Before starting our journey we should first define what OpenGL actually is. OpenGL is mainly considered an API (anApplication Programming Interface) that provides us with a large set of functions that we can use to manipulate graphics and images. However, OpenGL by itself is not an API, but merely a specification, developed and maintained by the [Khronos Group](http://www.khronos.org/).

    在开始我们的学习之旅之前首先定义下什么是OpenGL。OpenGL主要被认为是一个API(anApplication Programming Interface:应用程序编程接口),它为我们提供了大量的功能,我们可以使用它来处理图形和图像。然而,OpenGL本身并不是一个API,只是一个规范,由Khronos组织开发和维护。

    The OpenGL specification specifies exactly what the result/output of each function should be and how it should perform. It is then up to the developers implementing this specification to come up with a solution of how this function should operate. Since the OpenGL specification does not give us implementation details, the actual developed versions of OpenGL are allowed to have different implementations, as long as their results comply with the specification (and are thus the same to the user).

    OpenGL规范指定每个函数应该有确切结果或输出以及如何执行。然后开发人员根据这个规范提出一个方案来运行这个函数。由于OpenGL规范没有给我们具体实现细节,实际开发可以有不同的实现方式,只要结果符合规范就行。

    The people developing the actual OpenGL libraries are usually the graphics card manufacturers. Each graphics card that you buy supports specific versions of OpenGL which are the versions of OpenGL developed specifically for that card (series). When using an Apple system the OpenGL library is maintained by Apple themselves and under Linux there exists a combination of graphic suppliers' versions and hobbyists' adaptations of these libraries. This also means that whenever OpenGL is showing weird behavior that it shouldn't, this is most likely the fault of the graphics cards manufacturers (or whoever developed/maintained the library).

    实际上OpenGL库的通常是显卡制造商开发。你买的每个显卡所支持的OpenGL 都是特定的版本。当使用mac系统OpenGL库是由苹果开发,在Linux下存在一个架构来兼容不同的版本和功能。这也意味着只要OpenGL不是很特殊都会被识别(不再谁开发/谁维护)。

    Since most implementations are built by graphics card manufacturers. Whenever there is a bug in the implementation this is usually solved by updating your video card drivers; those drivers include the newest versions of OpenGL that your card supports. This is one of the reasons why it's always advised to occasionally update your graphic drivers.

    因为大多数的方案都是由制造商完成。每当方案中出现一个Bug,通常是通过更新驱动程序来解决,这些驱动程序包括您的显卡所支持的OpenGL的最新版本。这也是一个为什么建议偶尔更新显卡驱动的原因。

    Khronos publicly hosts all specification documents for all the OpenGL versions. The interested reader can find the OpenGL specification of version 3.3 (which is what we'll be using) here which is a good read if you want to delve into the details of OpenGL (note how they mostly just describe results and not implementations). The specifications also provide a great reference for finding the exact workings of its functions.

    Khronos公开了所有版本OpenGL的规范文档,如果你想深入的了解OpenGL(他们大多只是描述结果并没有实现)感兴趣的读者可以找到OpenGL规范的3.3版(我们将使用的)进行阅读。规范还提供了很好的参考来寻找函数的具体功能。

    Core-profile vs Immediate mode

    In the old days, using OpenGL meant developing in immediate mode (also known as the fixed function pipeline) which was an easy-to-use method for drawing graphics. Most of the functionality of OpenGL was hidden in the library and developers did not have much freedom at how OpenGL does its calculations. Developers eventually got hungry for more flexibility and over time the specifications became more flexible; developers gained more control over their graphics. The immediate mode is really easy to use and understand, but it is also extremely inefficient. For that reason the specification started to deprecate immediate mode functionality from version 3.2 and started motivating developers to develop in OpenGL's core-profile mode which is a division of OpenGL's specification that removed all old deprecated functionality.

    过去,使用OpenGL意味着用Immediate mode(也称为固定功能流水法)这是一个简单易用的绘制图形方法。大部分OpenGL的功能是隐藏在lib中,开发者没有支配OpenGL如何计算的权限。开发人员渴望更大的灵活性,随着时间的推移,规范变得更加灵活;开发人员获得更多的权限来控制图形。Immediate mode很容易使用和理解,但是非常低效。因此规范从3.2版开始不赞成使用Immediate mode功能,开始激励开发人员用核心组合模式开发OpenGL。 OpenGL规范中删除了所有弃用的功能。

    When using OpenGL's core-profile, OpenGL forces us to use modern practices. Whenever we try to use one of OpenGL's deprecated functions, OpenGL raises an error and stops drawing. The advantage of learning the modern approach is that it is very flexible and efficient, but unfortunately is also more difficult to learn. The immediate mode abstracted quite a lot from the actual operations OpenGL performed and while it was easy to learn, it was hard to grasp how OpenGL actually operates. The modern approach requires the developer to truly understand OpenGL and graphics programming and while it is a bit difficult, it allows for much more flexibility, more efficiency and most importantly a much better understanding of graphics programming.

    当使用OpenGL的core-profile开发时,OpenGL迫使我们使用最新的技术。每当我们尝试使用OpenGL的弃用功能时,OpenGL会提示出了一个错误并停止运行。新技术的优点是,非常灵活和高效,但不幸的是更加难学。 而immediate mode抽象出很多执行与操作所以很容易学习,但是很难理解OpenGL实际上是如何运作的。最新的方法需要开发人员真正理解OpenGL和图形编程,虽然它有点困难,但它有更大的灵活性,更高的效率,最重要的是易于的理解。

    This is also the reason why our tutorials are geared at Core-Profile OpenGL version 3.3. Although it is more difficult, it is greatly worth the effort.

    这也是为什么我们的教程的Core-Profile 是OpenGL 3.3版本。尽管它是更加困难,非常值得我们为之付出。

    As of today, much higher versions of OpenGL are published (at the time of writing 4.5) at which you might ask: why do I want to learn OpenGL 3.3 when OpenGL 4.5 is out? The answer to that question is relatively simple. All future versions of OpenGL starting from 3.3 basically add extra useful features to OpenGL without changing OpenGL's core mechanics; the newer versions just introduce slightly more efficient or more useful ways to accomplish the same tasks. The result is that all concepts and techniques remain the same over the modern OpenGL versions so it is perfectly valid to learn OpenGL 3.3. Whenever you're ready and/or more experienced you can easily use specific functionality from more recent OpenGL versions.

    截至今天,OpenGL的更高版本已经发布(在撰写本文时4.5),你可能会问:OpenGL 4.5 已经发布了为什么我想学OpenGL 3.3?这个问题的答案是相当简单的。基本上所有高版本的OpenGL都是基于3.3而添加一些有用的特性,但是OpenGL的核心机制是不曾改变的;新版本仅仅引进更高效、更有用的方式来完成同样的任务。由于所有的概念和技术在最新版保持不变,所以学习OpenGL 3.3是很有效的。只要你准备好了或有了丰富的经验您可以很容易地使用最新的OpenGL。

    When using functionality from the most recent version of OpenGL, only the most modern graphics cards will be able to run your application. This is often why most developers generally target lower versions of OpenGL and optionally enable higher version functionality.

    当使用OpenGL最新版本的功能时,只有最新的显卡能够运行您的应用程序。这通常是为什么大多数开发人员适配低版本的OpenGL和选择性地启用高版本的功能。

    In some tutorials you'll sometimes find more modern features which are noted down as such.

    在其他一些教程,你有时会发现更多的新特性被写了下来。

    Extensions

    A great feature of OpenGL is its support of extensions. Whenever a graphics company comes up with a new technique or a new large optimization for rendering this is often found in an extension implemented in the drivers. If the hardware an application runs on supports such an extension the developer can use the functionality provided by the extension for more advanced or efficient graphics. This way, a graphics developer can still use these new rendering techniques without having to wait for OpenGL to include the functionality in its future versions, simply by checking if the extension is supported by the graphics card. Often, when an extension is popular or very useful it eventually becomes part of future OpenGL versions.

    OpenGL的一个重要的特性是其对扩展的支持。每当一个图形公司提出了一项新技术或新的大型优化渲染技术,你会发现经常是扩展在驱动程序中实现。如果应用程序所运行的硬件支持这样一个扩展,开发者就可以使用其来提供更高级的或有效的图形的扩展功能。通过这种方式,图形开发人员就只需检查显卡是否支持扩展然后就使用这些新的渲染技术,而不用等待新的版本包含这些功能。通常,当一个扩展非常流行或非常有用,它最终就会变成未来的OpenGL的一部分。

    The developer then has to query whether any of these extensions are available (or use an OpenGL extension library). This allows the developer to do things better or more efficient, based on whether an extension is available:

    开发人员必须查询这些扩展(或使用一个OpenGL扩展库)是否可用。这使开发人员可以将事情做得更好更有效率,基于一个扩展是否可用:
    if(GL_ARB_extension_name){
      {
    
        // Do cool new and modern stuff supported by hardware
      }
    }else{
      {
        // Extension not supported: do it the old way
      }
    }
    

    With OpenGL version 3.3 we rarely need an extension for most techniques, but wherever it is necessary proper instructions are provided.

    对于大多数技术来说,OpenGL 3.3版本我们很少需要一个扩展,但无论如何它是一个必要的指令。

    State machine

    状态机

    OpenGL is by itself a large state machine: a collection of variables that define how OpenGL should currently operate. The state of OpenGL is commonly referred to as the OpenGL context. When using OpenGL, we often change its state by setting some options, manipulating some buffers and then render using the current context.

    OpenGL本身是一个大的状态机:用来定义目前OpenGL应该如何操作的一组变量。OpenGL的状态通常称为OpenGL context。当使用OpenGL,我们经常通过设置一些选项、操纵一些缓冲来改变他的状态,然后渲染使用当前上下文。

    Whenever we tell OpenGL that we now want to draw lines instead of triangles for example, we change the state of OpenGL by changing some context variable that sets how OpenGL should draw. As soon as we changed the state by telling OpenGL it should draw lines, the next drawing commands will now draw lines instead of triangles.

    例如每当我们告诉OpenGL,我们现在想画线,而不是三角形时,我们改变OpenGL的状态是通过改变一些上下文变量集合来决定怎么画。当我们改变了状态,告诉OpenGL绘制线条的时候,接下来绘制命令将画线而不是三角形。

    When working in OpenGL we will come across several state-changing functions that change the context and several state-using functions that perform some operations based on the current state of OpenGL. As long as you keep in mind that OpenGL is basically one large state machine, most of its functionality will make more sense.

    当致力于OpenGL时,我们将遇到几个状态改变函数来改变上下午,几个状态使用函数执行一些基于OpenGL当前状态的操作。只要你记住,OpenGL基本上是一个大的状态机,它的大部分功能将带来更多的意义。

    Objects

    The OpenGL libraries are written in C and allows for many derivations in other languages, but in its core it remains a C-library. Since many of C's language-constructs do not translate that well to other higher-level languages, OpenGL was developed with several abstractions in mind. One of those abstractions are objects in OpenGL.

    OpenGL库都是用C编写的,并且允许派生在其他语言中,但其核心仍然是一个C库。因为许多C语言结构不用转换为其他高级语言,OpenGL开发有几个抽象。其中的一个抽象就是对象。

    An object in OpenGL is a collection of options that represents a subset of OpenGL's state. For example, we could have an object that represents the settings of the drawing window; we could then set its size, how many colors it supports and so on. One could visualize an object as a C-like struct:

    对象在OpenGL里是一个选项的集合用来表示一个子集OpenGL的状态。例如,我们可以有一个对象,代表的设置窗口;我们可以设置它的大小,它支持的颜色等等。可以实现一个对象的c结构:
    struct object_name {
        GLfloat option1;
        GLuint option2;
        GLuint option2;
        GLchar[] name;
    };
    

    Primitive types
    原始类型

    Note that when working in OpenGL it is advised to use the primitive types defined by OpenGL. Instead of writing float we prefix it with GL; the same holds for int, uint, char, bool etc. OpenGL defines the memory-layout of their GL primitives in a cross-platform manner since some operating systems may have different memory-layouts for their primitive types. Using OpenGL's primitive types helps to ensure that your application works on multiple platforms.

    注意,在OpenGL中建议使用OpenGL定义的原始类型。而不是写GL前缀的浮点类型;同样的适用于int,uint,char,bool等等。因为一些操作系统可能有不同的memory-layouts原始类型所以OpenGL以跨平台的方式定义了内存布局原型。使用OpenGL的原始类型有助于确保您的应用程序可以在多种平台上运行。

    Whenever we want to use objects it generally looks something like this (with OpenGL's context visualized as a large struct):

    每当我们想要使用对象通常是这样的(与OpenGL的上下文可视化为大型结构):
    // The State of OpenGL
    struct OpenGL_Context {
        ...
        object* object_Window_Target;
        ...
    };
    
    // Create object
    GLuint objectId = 0;
    glGenObject(1, &objectId);
    // Bind object to context
    glBindObject(GL_WINDOW_TARGET, objectId);
    // Set options of object currently bound to GL_WINDOW_TARGET
    glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
    glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
    // Set context target back to default
    glBindObject(GL_WINDOW_TARGET, 0);
    

    This little piece of code is a workflow you'll frequently see when working in OpenGL. We first create an object and store a reference to it as an id (the real object data is stored behind the scenes). Then we bind the object to the target location of the context (the location of the example window object target is defined as GL_WINDOW_TARGET). Next we set the window options and finally we un-bind the object by setting the current object id of the window target to 0. The options we set are stored in the object referenced by objectId and restored as soon as we bind the object back to GL_WINDOW_TARGET.

    这一小段代码是一个工作流时,你经常会在OpenGL中看到。我们首先创建一个对象并存储引用id(真正的对象数据存储在幕后)。然后我们将对象绑定到目标位置的上下文(例如窗口对象的位置目标被定义为GL_WINDOW_TARGET)。接下来,我们设置窗口选项,最后我们通过设置当前窗口的对象id目标为0来释放对象。我们通过objectId来吧设置的选项存储在对象引用,回复是尽快返回GL_WINDOW_TARGET来绑定对象。

    The code samples provided so far are only approximations of how OpenGL operates; throughout the tutorial you will come across enough actual examples.

    这段代码是迄今为止提供的唯一接近OpenGL如何运作的示例;在整个教程中,您将遇到更多例子。

    The great thing about using these objects is that we can define more than one object in our application, set their options and whenever we start an operation that uses OpenGL's state, we bind the object with our preferred settings. There are objects for example that act as container objects for 3D model data (a house or a character) and whenever we want to draw one of them, we bind the object containing the model data that we want to draw (we first created and set options for these objects). Having several objects allows us to specify many models and whenever we want to draw a specific model, we simply bind the corresponding object before drawing without setting all their options again.

    使用这些对象的好处是,我们可以在我们的应用程序定义一个以上的对象,设置他们的选项,当我们使用OpenGL的状态开始操作时,我们用首选的设置来绑定对象。例如有些对象作为三维模型数据的容器对象(一个房子或者一个字符),每当我们想画其中一个,我们把我们想画的东西(我们第一次创建这些对象和设置选项)与包含模型数据的对象绑定。每当我们想画一个特定的模型,有几个对象允许我们指定许多模型,我们只需绑定对应的对象而不是设置所有选项。

    Let's get started

    You now learned a bit about OpenGL as a specification and a library, how OpenGL approximately operates under the hood and a few custom tricks that OpenGL uses. Don't worry if you didn't get all of it; throughout the tutorial we'll walk through each step and you'll see enough examples to really get a grasp of OpenGL. If you're ready for the next step we can start creating an OpenGL context and our first window here.

    你现在学了一点关于OpenGL作为一个规范和一个库的知识,OpenGL的底层操作和一些自定义的使用技巧。不要担心你没有完全理解,在本教程中我们将一步步走过,你将会看到足够的例子来真正理解OpenGL。如果你已准备好,我们就可以开始我们下一步的学习了。

    #######欢迎大家关注我的公众号,分享点滴生活,分享开发所得


    ForgetFairy.jpg

    相关文章

      网友评论

        本文标题:1.1什么是OpenGL

        本文链接:https://www.haomeiwen.com/subject/tmxnsttx.html