如何将OpenGL绘图分成类
Posted
技术标签:
【中文标题】如何将OpenGL绘图分成类【英文标题】:How to separate OpenGL drawing into classes 【发布时间】:2013-07-12 21:13:17 【问题描述】:假设我只想绘制一个简单的 OpenGL 三角形。我知道我可以在主文件中绘制一个三角形,我所有的 OpenGL 东西都是通过以下方式设置的:
glBegin( GL_TRIANGLES );
glVertex3f( 0.0f, 1.0f, 0.0f );
glVertex3f( -1.0f,-1.0f, 0.0f );
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
但是我不想在我的主文件中包含所有这些杂乱无章的东西,而是想通过使用一个名为“Triangle”的类和一个“Draw”函数来绘制一个三角形,所以我的代码看起来像这样:
Triangle TheTriangle;
TheTriangle.draw();
简而言之,我怎样才能用一些可以通过函数绘制的 OpenGL 形状来创建一个类?
【问题讨论】:
那是老式的 OpenGL。为什么不使用更新的基于着色器的 API? 我刚开始使用 OpenGL...我不知道基于着色器的 API 是什么。你能解释一下吗? duriansoftware.com/joe/… 谢谢。看起来他们正在使用 GLUT,有人告诉我 GLUT 不是最好的,所以我要使用 SDL。我不确定这是否会改变任何事情。 GLUT 将 OpenGL 连接到您的窗口系统。你可以使用任何你想要的东西。 OpenGL 功能是一样的。 【参考方案1】:通常的方式如下:
TriangleArray tri;
tri.push_back(...);
tri.prepare();
while(1)
clear();
tri.draw();
swapbuffers();
但通常同一个类应该处理对象数组,而不仅仅是一个对象。所以 TriangleArray 是一个很好的类名。 prepare() 用于设置纹理或顶点数组。 (注意:如果您的世界是由立方体构建的,则您将创建 CubeArray。)
【讨论】:
谢谢!我仍然有点不清楚如何实现它......我到底要推回数组什么? API 定义很大程度上取决于您。如果我这样做,作为第一次迭代,我会有一个 push_back(),它需要三个 3 元组或 Vector3D 对象(或 9 个实数>_>),并将坐标附加到我想要的内存缓冲区最终使用 glBindBuffer、glBufferData 等上传到 GPU。读取顶点缓冲区 - 它们比使用 glVertex3f() 等定义单个顶点要快得多。【参考方案2】:正如一些人所说,OpenGL 在面向对象编程方面表现不佳,但这并不意味着它不能完成。从理论上讲,简单地说,您可以拥有一个“网格”容器,您可以在其中循环遍历每一帧并将每一帧渲染到屏幕上。 Render 类可以被认为是状态的管理器,以及各种场景模块的容器。实际上,大多数系统都比这复杂得多,并实现了场景图等结构。
首先,尝试创建一个网格类和一个对象类(可能指向要绘制的网格)添加功能以从容器中添加和删除对象。每一帧,循环遍历并渲染每个三角形(或任何你想要的),你就有了一个非常简单的 OO 架构。这将是让你开始的一种方式。
使用 OOP 封装功能强大的架构很奇怪,这很正常,但您确实习惯了它,如果操作正确,它可以使您的代码更易于维护和扩展。话虽如此,我给出的示例非常简单,所以这里有一个架构,一旦你完成它,你可能想要探索它。
以下链接提供了一些关于场景图到底是什么的有用信息:Chapter 6 covers the scene graph
它是一个非常强大的架构,可让您以非常复杂和高效(如果您利用这些优势)的方式对场景进行分区和排序。还有许多其他技术,但我发现这对游戏开发人员来说是最强大的。这完全取决于您要创建的应用程序类型。尽管如此,我不建议制作一个完全面向对象的渲染器。根据您的应用程序,OO 场景图可能就足够了。总之,祝你好运!
【讨论】:
【参考方案3】:您可以将 OpenGL 代码放在 Triangle::draw() 函数中:
void Triangle::draw()
glBegin( GL_TRIANGLES );
glVertex3f( 0.0f, 1.0f, 0.0f );
glVertex3f( -1.0f,-1.0f, 0.0f );
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
当然,这假设您已经在Triangle
类中正确声明了draw()
方法,并且您已经初始化了OpenGL 环境。
【讨论】:
【参考方案4】:OpenGL 并没有真正映射到 OOP 范式中。实现面向对象的渲染系统是完全可能的,但是 OpenGL API 和它的许多低级概念非常困难,甚至不可能转换为类。
有关详细信息,请参阅类似问题的答案:https://***.com/a/12091766/524368
【讨论】:
以上是关于如何将OpenGL绘图分成类的主要内容,如果未能解决你的问题,请参考以下文章
添加到 QGraphicsScene 时如何更新 OpenGL 绘图(QOpenGLWidget)?