【问题标题】:Understanding OpenGL了解 OpenGL
【发布时间】:2011-12-19 14:30:23
【问题描述】:

我有一些关于 OpenGL 的基本观点/问题,不仅涉及代码,还涉及概念。如果您能回答、肯定或扩展其中任何一个,我将不胜感激。我警告你,有些人可能很幼稚,所以请多多包涵。

  1. 我知道 OpenGL 只是一个标准,而不是一个软件。例如,“获取”OpenGL 实际上涉及获取第三方实现,该实现不一定必须得到 Khronos 的认可。

  2. OpenGL 通常指的是 GL 实用程序 (GLU) 和 GL 实用程序工具包 (GLUT) 的组合。他们有以gluglut 开头的方法,分别是。而以gl 开头的“基本”OpenGL 方法是由那些制作图形驱动程序的公司(即NVIDIA)实现的?

  3. 我假设 glut 方法是特定于操作系统的助手,例如 glutKeyboardFunc() 必须是,才能解释键盘。因此,如果我想要一种更强大的替代方法来解释键盘输入,我只会使用 OS API。 OpenGL 本身纯粹是关于图形的,但 glut 有这种东西,因为图形没有多少没有实时的人工控制。

  4. 在我看来glu 方法可能与调用一系列较低级别的gl 方法相同。我想引用的一个例子是glOrtho()gluPerspective()。在我看来,它们的工作方式相似,但计算透视可能更复杂,所以gluPerspective() 是为了方便起见,但可能只解决一些gl 方法。

  5. 我在大学使用 freeglut 学习了基本的 OpenGL,并且我一直有这种使用 OpenGL 的“核心”方式的愿景,只使用低级方法。我不知道这是否是一个完全幼稚的想法,但是是否有一种“专业”的方式来编写 OpenGL,以发挥其最大的功能?比如,大概游戏开发者不会使用glutPostRedisplay(),对吧?这似乎太容易和方便了,就像它隐藏了很多正在发生的事情一样。我怀疑 C++ 也是如此,因为 GLUT 回调对命名空间中的方法不友好(正如我在其他问题中看到的那样)。

【问题讨论】:

  • 这个问题有时有点模糊,应该分成几个不同的问题。
  • 哦,我很抱歉;找到了 (4) 的答案

标签: c++ c opengl


【解决方案1】:

\ 1. 我理解OpenGL只是一个标准,而不是一个软件。例如,“获取”OpenGL 实际上涉及获取 不一定必须是第三方实现 得到 Khronos 的认可。

确实。

\ 2. OpenGL 通常是指 GL 实用程序 (GLU) 和 GL 实用程序工具包 (GLUT) 的组合。他们有方法以 gluglut,分别。以及开始的“基本”OpenGL方法 只需gl,由那些制作图形驱动程序的人实现, 即英伟达?

没有。 OpenGL 只是以gl… 开头的函数。其他所有内容(GLU、GLUT)都是第三方库,OpenGL 未涵盖。

\ 3. 我假设glut 方法是特定于操作系统的助手,例如glutKeyboardFunc() 必须是,才能解释键盘。所以如果我 想要一种更强大的替代方式来解释键盘输入,我 只会使用操作系统 API。 OpenGL 本身纯粹是关于图形的,但是 glut 有这样的东西,因为图形不多 实时人工控制。

正确。 GLUT 是一个非常小的框架,因此强烈建议使用其他框架。

\ 4. 在我看来glu 方法可能与调用一系列较低级别的gl 方法相同。我想引用一个例子 是glOrtho()gluPerspective()

我认为您指的是gluOrtho2D,但是是的,您是正确的。 glOrtho 是真正的 OpenGL-1 函数。在某种程度上,gluOrtho2D 是有史以来最没用的函数之一:

void gluOrtho2D(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top)
{
    glOrtho(left, right, bottom, top, -1, 1);
}

在我看来他们有相似之处 工作方式,但计算视角可能更复杂,所以 gluPerspective() 是为了方便,但可能只是解决一些问题 gl 方法。

又对了,但其实很简单:

gluPrespective(GLfloat fov, GLfloat aspect, GLfloat near, GLfloat far)
{
    GLfloat a = 0.5 * atan(fov);
    glFrustum(-a*near, a*near, -a*near/aspect, a*near/aspect, near, far);
}

从 OpenGL-3 核心开始,整个矩阵操作的东西都被删除了。在任何严肃的应用程序中,它都没有什么用处,因为无论如何您都将自己管理矩阵。

\ 5. 我在大学使用 freeglut 学习了基本的 OpenGL,并且我一直有这种使用 OpenGL 的“硬核”方式的愿景,使用 只有低级方法。我不知道这是否完全幼稚 想过,但是有没有一种“专业”的方式来编写 OpenGL,以获得 发挥其最大功能?就像,大概,游戏开发者 例如,不会使用glutPostRedisplay(),对吧?

是的,这是可能的,而且大多数游戏引擎确实可以自己完成所有繁重的工作。 有 libSDL,它也涵盖了 OpenGL。事实上,我个人更喜欢 GLFW 或自己做这些事情。然而,这并没有改变人们使用 OpenGL 本身的方式。但这只是基础设施,主要是编写样板代码。作为初学者,如果不使用已建立的框架,您只会获得很少的收益。如果您的程序大量使用 GUI 小部件,那么使用 Qt 或 GTK 及其嵌入式 OpenGL 小部件是一个合理的选择。

但是有些项目非常硬核,并且也使用 OpenGL 实现了整个 GUI。 Blender 是最极端的例子,我喜欢它。

它看起来太简单方便了,就像它隐藏了很多正在发生的事情一样。一世 怀疑这对于 C++ 也是如此,因为 GLUT 回调不友好 使用命名空间中的方法(正如我在其他问题中看到的那样)。

GLUT 回调可以用于命名空间(命名空间只是 C++ 编译时的事情)。但是不可能将类实例方法作为 GLUT/C 回调传递。

【讨论】:

  • 感谢您抽出宝贵时间撰写此简明答案。我现在已经开始阅读 freeglut 源代码以找出其他未知数!我会推荐其他好奇的人也这样做。
  • 在使用std::bind(&Foo::callback, &instanceoffoo) afaik 绑定实例后,您可以将类实例方法传递给回调。
  • @WorldSEnder: std::bind 创建一个 C++ 可调用对象。本质上是一个类实例,其中operator() 将实例与指向成员的指针合并以调用它。但这最终会导致您遇到与之前完全相同的问题,您只是在其上添加了一层相同的问题:您有一个 C++ 类实例和一些要使用该实例调用的函数。现在,如果您可以将用户定义的void* 传递给 GLUT 以传递给回调。但是你不需要那个std::bind,你只需要dynamic_cast<…>(ptr)->method(…)就可以了。
  • stackoverflow.com/questions/13238050/… 可以解决这个问题
  • @WorldSEnder:嗯,一个可能的解决方案。但是您仍然停留在思考 C++ 中。想想更脏,不要试图用 C++ 解决这个问题。也不用 C。是时候做“坏”的事情了,比如在运行时创建代码。看看LibFFCall,希望你能明白我的意思。或者DynCall,它是 BSD 等价物。
【解决方案2】:

您似乎对 OpenGL 和接受它有一个很好的概念。不知道还有什么要说的。 我想(5)确实是可以评论的地方。

根据您正在构建的应用程序类型,您认为有些人会选择仅使用本机 GL 调用来构建他们的应用程序是正确的。

例如,如果您在具有 OpenGL 视图以及标准菜单和工具栏的 windows 下构建单个文档应用程序,那么您很有可能希望直接使用 c++ 和所谓的“低级”api .

但是,如果您在全屏模式下构建低节奏游戏,那么如果 Glut 或任何其他工具包可以简化您的应用程序开发,那么您没有理由不使用它。

您直接单独使用 GLut 或低级调用这一事实不会使应用程序变得更好或更差 :)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2017-04-14
    • 1970-01-01
    • 2011-08-10
    • 2021-06-03
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多